Case study: Lengte van mannen en vrouwen - Variabiliteit van steekproef tot steekproef
Om te begrijpen dat een steekproef random is zouden we hetzelfde experiment veel keer moeten kunnen herhalen (repeated sampling).
Dan zouden we inzicht kunnen krijgen hoe de gegevens veranderen van steekproef tot steekproef.
Om dit te illustreren zullen we gebruik maken van een hele grote studie.
Uit die studie zullen we dan herhaaldelijk kleine steekproeven trekken om te begrijpen hoe de gegevens en statistieken veranderen van steekproef tot steekproef. Of om met andere woorden na te gaan wat de variabiliteit is tussen steekproeven.
National Health And Nutrition Examination Study (NHANES)
- Sinds 1960 worden elk jaar mensen van alle leeftijden geïnterviewd bij hen thuis.
- Er maakt ook een gezondheidsonderzoek deel uit van de study die in een mobiel onderzoekscentrum wordt afgenomen.
- We zullen deze grote studie gebruiken om at random personen te selecteren van de Amerikaanse populatie.
- Dat zal inzicht geven in hoe de gegevens en resultaten van een analyse zullen variëren van steekproef tot steekproef.
- De data van deze studie is terug te vinden in het R pakket
NHANES
library(NHANES)
head(NHANES)
# A tibble: 6 x 76
ID SurveyYr Gender Age AgeDecade AgeMonths Race1 Race3 Education
<int> <fct> <fct> <int> <fct> <int> <fct> <fct> <fct>
1 51624 2009_10 male 34 " 30-39" 409 White <NA> High Sch…
2 51624 2009_10 male 34 " 30-39" 409 White <NA> High Sch…
3 51624 2009_10 male 34 " 30-39" 409 White <NA> High Sch…
4 51625 2009_10 male 4 " 0-9" 49 Other <NA> <NA>
5 51630 2009_10 female 49 " 40-49" 596 White <NA> Some Col…
6 51638 2009_10 male 9 " 0-9" 115 White <NA> <NA>
# … with 67 more variables: MaritalStatus <fct>, HHIncome <fct>,
# HHIncomeMid <int>, Poverty <dbl>, HomeRooms <int>, HomeOwn <fct>,
# Work <fct>, Weight <dbl>, Length <dbl>, HeadCirc <dbl>, Height <dbl>,
# BMI <dbl>, BMICatUnder20yrs <fct>, BMI_WHO <fct>, Pulse <int>,
# BPSysAve <int>, BPDiaAve <int>, BPSys1 <int>, BPDia1 <int>,
# BPSys2 <int>, BPDia2 <int>, BPSys3 <int>, BPDia3 <int>,
# Testosterone <dbl>, DirectChol <dbl>, TotChol <dbl>, UrineVol1 <int>,
# UrineFlow1 <dbl>, UrineVol2 <int>, UrineFlow2 <dbl>, Diabetes <fct>,
# DiabetesAge <int>, HealthGen <fct>, DaysPhysHlthBad <int>,
# DaysMentHlthBad <int>, LittleInterest <fct>, Depressed <fct>,
# nPregnancies <int>, nBabies <int>, Age1stBaby <int>,
# SleepHrsNight <int>, SleepTrouble <fct>, PhysActive <fct>,
# PhysActiveDays <int>, TVHrsDay <fct>, CompHrsDay <fct>,
# TVHrsDayChild <int>, CompHrsDayChild <int>, Alcohol12PlusYr <fct>,
# AlcoholDay <int>, AlcoholYear <int>, SmokeNow <fct>, Smoke100 <fct>,
# Smoke100n <fct>, SmokeAge <int>, Marijuana <fct>, AgeFirstMarij <int>,
# RegularMarij <fct>, AgeRegMarij <int>, HardDrugs <fct>, SexEver <fct>,
# SexAge <int>, SexNumPartnLife <int>, SexNumPartYear <int>,
# SameSex <fct>, SexOrientation <fct>, PregnantNow <fct>
Observations: 10,000
Variables: 76
$ ID <int> 51624, 51624, 51624, 51625, 51630, 51638, 51646…
$ SurveyYr <fct> 2009_10, 2009_10, 2009_10, 2009_10, 2009_10, 20…
$ Gender <fct> male, male, male, male, female, male, male, fem…
$ Age <int> 34, 34, 34, 4, 49, 9, 8, 45, 45, 45, 66, 58, 54…
$ AgeDecade <fct> 30-39, 30-39, 30-39, 0-9, 40-49, 0-9, 0-…
$ AgeMonths <int> 409, 409, 409, 49, 596, 115, 101, 541, 541, 541…
$ Race1 <fct> White, White, White, Other, White, White, White…
$ Race3 <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ Education <fct> High School, High School, High School, NA, Some…
$ MaritalStatus <fct> Married, Married, Married, NA, LivePartner, NA,…
$ HHIncome <fct> 25000-34999, 25000-34999, 25000-34999, 20000-24…
$ HHIncomeMid <int> 30000, 30000, 30000, 22500, 40000, 87500, 60000…
$ Poverty <dbl> 1.36, 1.36, 1.36, 1.07, 1.91, 1.84, 2.33, 5.00,…
$ HomeRooms <int> 6, 6, 6, 9, 5, 6, 7, 6, 6, 6, 5, 10, 6, 10, 10,…
$ HomeOwn <fct> Own, Own, Own, Own, Rent, Rent, Own, Own, Own, …
$ Work <fct> NotWorking, NotWorking, NotWorking, NA, NotWork…
$ Weight <dbl> 87.4, 87.4, 87.4, 17.0, 86.7, 29.8, 35.2, 75.7,…
$ Length <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ HeadCirc <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ Height <dbl> 164.7, 164.7, 164.7, 105.4, 168.4, 133.1, 130.6…
$ BMI <dbl> 32.22, 32.22, 32.22, 15.30, 30.57, 16.82, 20.64…
$ BMICatUnder20yrs <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ BMI_WHO <fct> 30.0_plus, 30.0_plus, 30.0_plus, 12.0_18.5, 30.…
$ Pulse <int> 70, 70, 70, NA, 86, 82, 72, 62, 62, 62, 60, 62,…
$ BPSysAve <int> 113, 113, 113, NA, 112, 86, 107, 118, 118, 118,…
$ BPDiaAve <int> 85, 85, 85, NA, 75, 47, 37, 64, 64, 64, 63, 74,…
$ BPSys1 <int> 114, 114, 114, NA, 118, 84, 114, 106, 106, 106,…
$ BPDia1 <int> 88, 88, 88, NA, 82, 50, 46, 62, 62, 62, 64, 76,…
$ BPSys2 <int> 114, 114, 114, NA, 108, 84, 108, 118, 118, 118,…
$ BPDia2 <int> 88, 88, 88, NA, 74, 50, 36, 68, 68, 68, 62, 72,…
$ BPSys3 <int> 112, 112, 112, NA, 116, 88, 106, 118, 118, 118,…
$ BPDia3 <int> 82, 82, 82, NA, 76, 44, 38, 60, 60, 60, 64, 76,…
$ Testosterone <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ DirectChol <dbl> 1.29, 1.29, 1.29, NA, 1.16, 1.34, 1.55, 2.12, 2…
$ TotChol <dbl> 3.49, 3.49, 3.49, NA, 6.70, 4.86, 4.09, 5.82, 5…
$ UrineVol1 <int> 352, 352, 352, NA, 77, 123, 238, 106, 106, 106,…
$ UrineFlow1 <dbl> NA, NA, NA, NA, 0.094, 1.538, 1.322, 1.116, 1.1…
$ UrineVol2 <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ UrineFlow2 <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ Diabetes <fct> No, No, No, No, No, No, No, No, No, No, No, No,…
$ DiabetesAge <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ HealthGen <fct> Good, Good, Good, NA, Good, NA, NA, Vgood, Vgoo…
$ DaysPhysHlthBad <int> 0, 0, 0, NA, 0, NA, NA, 0, 0, 0, 10, 0, 4, NA, …
$ DaysMentHlthBad <int> 15, 15, 15, NA, 10, NA, NA, 3, 3, 3, 0, 0, 0, N…
$ LittleInterest <fct> Most, Most, Most, NA, Several, NA, NA, None, No…
$ Depressed <fct> Several, Several, Several, NA, Several, NA, NA,…
$ nPregnancies <int> NA, NA, NA, NA, 2, NA, NA, 1, 1, 1, NA, NA, NA,…
$ nBabies <int> NA, NA, NA, NA, 2, NA, NA, NA, NA, NA, NA, NA, …
$ Age1stBaby <int> NA, NA, NA, NA, 27, NA, NA, NA, NA, NA, NA, NA,…
$ SleepHrsNight <int> 4, 4, 4, NA, 8, NA, NA, 8, 8, 8, 7, 5, 4, NA, 5…
$ SleepTrouble <fct> Yes, Yes, Yes, NA, Yes, NA, NA, No, No, No, No,…
$ PhysActive <fct> No, No, No, NA, No, NA, NA, Yes, Yes, Yes, Yes,…
$ PhysActiveDays <int> NA, NA, NA, NA, NA, NA, NA, 5, 5, 5, 7, 5, 1, N…
$ TVHrsDay <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ CompHrsDay <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ TVHrsDayChild <int> NA, NA, NA, 4, NA, 5, 1, NA, NA, NA, NA, NA, NA…
$ CompHrsDayChild <int> NA, NA, NA, 1, NA, 0, 6, NA, NA, NA, NA, NA, NA…
$ Alcohol12PlusYr <fct> Yes, Yes, Yes, NA, Yes, NA, NA, Yes, Yes, Yes, …
$ AlcoholDay <int> NA, NA, NA, NA, 2, NA, NA, 3, 3, 3, 1, 2, 6, NA…
$ AlcoholYear <int> 0, 0, 0, NA, 20, NA, NA, 52, 52, 52, 100, 104, …
$ SmokeNow <fct> No, No, No, NA, Yes, NA, NA, NA, NA, NA, No, NA…
$ Smoke100 <fct> Yes, Yes, Yes, NA, Yes, NA, NA, No, No, No, Yes…
$ Smoke100n <fct> Smoker, Smoker, Smoker, NA, Smoker, NA, NA, Non…
$ SmokeAge <int> 18, 18, 18, NA, 38, NA, NA, NA, NA, NA, 13, NA,…
$ Marijuana <fct> Yes, Yes, Yes, NA, Yes, NA, NA, Yes, Yes, Yes, …
$ AgeFirstMarij <int> 17, 17, 17, NA, 18, NA, NA, 13, 13, 13, NA, 19,…
$ RegularMarij <fct> No, No, No, NA, No, NA, NA, No, No, No, NA, Yes…
$ AgeRegMarij <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 20,…
$ HardDrugs <fct> Yes, Yes, Yes, NA, Yes, NA, NA, No, No, No, No,…
$ SexEver <fct> Yes, Yes, Yes, NA, Yes, NA, NA, Yes, Yes, Yes, …
$ SexAge <int> 16, 16, 16, NA, 12, NA, NA, 13, 13, 13, 17, 22,…
$ SexNumPartnLife <int> 8, 8, 8, NA, 10, NA, NA, 20, 20, 20, 15, 7, 100…
$ SexNumPartYear <int> 1, 1, 1, NA, 1, NA, NA, 0, 0, 0, NA, 1, 1, NA, …
$ SameSex <fct> No, No, No, NA, Yes, NA, NA, Yes, Yes, Yes, No,…
$ SexOrientation <fct> Heterosexual, Heterosexual, Heterosexual, NA, H…
$ PregnantNow <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
Data exploratie
Onderzoeksvraag: hoe verschilt de lengte van volwassen mannen en vrouwen.
- We pipen de dataset naar de function
filter om de data te filteren volgens leeftijd.
- We plotten de lengte metingen.
- We selecteren de data data met het commando
ggplot(aes(x=lengte))
- We voegen een histogram toe met het commando
geom_histogram()
- We maken twee vertikale panels met het commando
facet_grid(Gender~.)
- We veranderen het label van de x-as met de
xlab functie.
NHANES%>%
filter(Age > 18 & !is.na(Height)) %>%
ggplot(aes(x = Height))+
geom_histogram() +
facet_grid(Gender ~ .) +
xlab("Lengte (cm)")

We zien dat de data nu min of meer symmetrisch verdeeld zijn en een klokvorm hebben.
Dat zal ons toe laten om de data verder samen te vatten door gebruik te maken van twee statistieken: het gemiddelde en de standaard deviatie wat een maat is voor de spreiding van de gegevens rond het gemiddelde.
We maken nu een subset van de data die we zullen gebruiken om aan te tonen hoe de variabiliteit in kleine steekproeven kan variëren van steekproef tot steekproef.
- We filteren op leeftijd en verwijderen ontbrekenden gegevens (NA, Not Available).
- We selecteren enkel het geslacht en Lengte zodat de dataset geen onnodige variabelen bevat.
nhanesSub <- NHANES %>%
filter(Age > 25 & !is.na(Height)) %>%
select(c("Gender","Height"))
We berekenen het gemiddelde en de standaard deviatie voor de lengte voor mannen en vrouwen in de grote dataset. We groeperen de data hiervoor op basis van het geslacht (variable Gender).
HeightSum <- nhanesSub %>%
group_by(Gender) %>%
summarize_at("Height",
list(mean = mean,
sd = sd)
)
knitr::kable(
HeightSum %>%
mutate_if(is.numeric, round, digits=1)
)
| female |
161.9 |
7.2 |
| male |
175.8 |
7.5 |
Experiment
Stel dat we geen toegang hebben tot de metingen van de NHANES studie.
We zouden dan een experiment op moeten zetten om metingen bij mannen en vrouwen te doen.
Veronderstel dat we budget hebben om metingen bij 5 mannen en 5 vrouwen te doen.
We zouden dan 5 mannen en 5 vrouwen boven de 25 jaar at random selecteren uit de Amerikaanse populatie.
We kunnen dit experiment simuleren door 5 vrouwen en 5 mannen at random te selecteren uit de NHANES studie.
set.seed(1000001)
nSamp <- 5
fem <- nhanesSub %>%
filter(Gender=="female") %>%
sample_n(size=5)
mal <- nhanesSub %>%
filter(Gender=="male") %>%
sample_n(size=5)
samp1 <- rbind(fem,mal)
samp1
# A tibble: 10 x 2
Gender Height
<fct> <dbl>
1 female 159.
2 female 168.
3 female 157.
4 female 155.
5 female 163.
6 male 178.
7 male 173.
8 male 187.
9 male 173.
10 male 185.
Data Exploratie
samp1 %>%
ggplot(aes(x=Height)) +
geom_histogram() +
facet_grid(Gender~.) +
xlab("Lengte (cm)")

HeightSumExp1 <- samp1 %>%
group_by(Gender) %>%
summarize_at("Height",
list(mean = mean,
sd = sd)
)
HeightSumExp1
# A tibble: 2 x 3
Gender mean sd
<fct> <dbl> <dbl>
1 female 161. 5.17
2 male 179. 6.49
Histogram is niet zinvol als we maar zo weinig datapunten hebben.
Boxplot is beter:

We voeren hier ook een t-test uit.
t.test(Height~Gender,data=samp1)
Welch Two Sample t-test
data: Height by Gender
t = -4.9713, df = 7.6177, p-value = 0.001261
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
-27.068985 -9.811015
sample estimates:
mean in group female mean in group male
160.62 179.06
In het experiment zijn vrouwen zijn gemiddeld 18.44 cm kleiner dan mannen. En als we een statistische test uitvoeren (zie hoofdstuk 5: Statistische besluitvorming) kunnen we besluiten dat dit verschil statistisch significant is.
Herhaal het experiment
Als we het experiment herhalen selecteren we andere mensen en verkrijgen we andere resultaten.
fem <- nhanesSub %>%
filter(Gender=="female") %>%
sample_n(size=5)
mal <- nhanesSub %>%
filter(Gender=="male") %>%
sample_n(size=5)
samp2 <- rbind(fem,mal)
HeightSumExp2 <- samp2 %>%
group_by(Gender) %>%
summarize_at("Height",
list(mean=mean,
sd=sd)
)
HeightSumExp2
# A tibble: 2 x 3
Gender mean sd
<fct> <dbl> <dbl>
1 female 169. 9.38
2 male 175. 6.12
samp2 %>%
ggplot(aes(x = Gender,y = Height)) +
geom_boxplot(outlier.shape = NA) +
geom_point(position = "jitter") +
geom_point(
aes(x = 1, y = HeightSumExp1$mean[1]),
size = 3,
pch = 17,
color="darkred") +
geom_point(
aes(x = 2, y = HeightSumExp1$mean[1]),
size = 3,
pch = 17,
color = "darkred") +
ylab("Height (cm)")

t.test(Height ~ Gender, data=samp2)
Welch Two Sample t-test
data: Height by Gender
t = -1.1379, df = 6.8813, p-value = 0.2932
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
-17.586435 6.186435
sample estimates:
mean in group female mean in group male
169.06 174.76
In de nieuwe steekproef zijn vrouwen zijn gemiddeld 5.7 cm kleiner dan mannen. En dit verschil is statistisch niet significant
Herhaal het experiment opnieuw
seed <- 1336602
fem <- nhanesSub %>%
filter(Gender=="female") %>%
sample_n(size=5)
mal <- nhanesSub %>%
filter(Gender=="male") %>%
sample_n(size=5)
samp3 <- rbind(fem,mal)
HeightSumExp3 <- samp3 %>%
group_by(Gender) %>%
summarize_at("Height",
list(mean=mean,
sd=sd)
)
HeightSumExp3
# A tibble: 2 x 3
Gender mean sd
<fct> <dbl> <dbl>
1 female 162. 12.5
2 male 170. 14.5
samp3 %>%
ggplot(aes(x = Gender,y = Height)) +
geom_boxplot(outlier.shape = NA) +
geom_point(position = "jitter") +
geom_point(
aes(x = 1, y = HeightSumExp1$mean[1]),
size = 3,
pch = 17,
color="darkred") +
geom_point(
aes(x = 2, y = HeightSumExp1$mean[1]),
size = 3,
pch = 17,
color = "darkred") +
ylab("Height (cm)")

t.test(Height ~ Gender, data=samp3)
Welch Two Sample t-test
data: Height by Gender
t = -0.99138, df = 7.8343, p-value = 0.3511
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
-28.34441 11.34441
sample estimates:
mean in group female mean in group male
161.96 170.46
In de nieuwe steekproef zijn vrouwen gemiddeld 8.5 cm kleiner dan mannen. En dit verschil is statistisch niet significant
Samenvatting
We trokken at random andere proefpersonen in elke steekproef
Hierdoor verschillen lengtemetingen van steekproef tot steekproef.
Dus ook de geschatte gemiddeldes en standaard deviaties.
Bijgevolg zijn onze conclusies ook onzeker en kunnen deze wijzigen van steekproef tot steekproef.
Steekproeven waarbij het effect tegengesteld is aan dat in de populatie en waarbij we besluiten dat het verschil significant is, zijn zeldzaam.
\(\rightarrow\) Met statistiek controleren we de kans op het trekken foute conclusies.
- Dit wordt in de onderstaande code geïllustreerd. We trekken 10000 herhaalde steekproeven van 5 vrouwen en 5 mannen uit de NHANES studie.
# Aantal simulaties en steekproefgrootte per groep
nSim <- 10000
nSamp <- 5
# We filteren de data vooraf zodat we dit niet telkens opnieuw hoeven te doen
fem <- nhanesSub %>%
filter(Gender == "female")
mal <- nhanesSub %>%
filter(Gender == "male")
# Simulatie studie
# Om snelle functies te kunnen gebruiken nemen we eerst nSim steekproeven en berekenen we daarna alles.
femSamps <- malSamps <-matrix(NA, nrow=nSamp, ncol=nSim)
for (i in 1:nSim)
{
femSamps[,i] <- sample(fem$Height, nSamp)
malSamps[,i] <- sample(mal$Height, nSamp)
}
res <- data.frame(
verschil=colMeans(femSamps) - colMeans(malSamps),
Rfast::ttests(femSamps, malSamps)
)
sum(res$pvalue < 0.05 & res$verschil < 0)
[1] 7148
[1] 2852
sum(res$pvalue < 0.05 & res$verschil>0)
[1] 0
res %>%
ggplot(aes(x=verschil,y=-log10(pvalue),color=pvalue < 0.05)) +
geom_point() +
xlab("Gemiddeld Verschil (cm)") +
ylab("Statistische Significantie (-log10 p)")

res %>%
ggplot(aes(y = verschil)) +
geom_boxplot() +
ylab("Gemiddeld Verschil (cm)")

$x
[1] ""
attr(,"class")
[1] "labels"
Op basis van 10 000 steekproeven van 5 mannen en 5 vrouwen zagen we dat in 7148 steekproeven vrouwen gemiddeld significant kleiner zijn dan mannen. In 2852 steekproeven besluiten we dat vrouwen en mannen gemiddeld niet significant verschillen in lengte. En in 0 besluiten we dat vrouwen gemiddeld significant groter zijn dan mannen.
- De steekproef die we toonden waaruit we zouden besluiten dat vrouwen significant groter zijn dan mannen is heel onwaarschijnlijk. Er moesten 1336602 steekproeven worden getrokken om deze extreme steekproef te vinden.
Het feit dat we in veel steekproeven resultaten vinden die statistisch niet significant zijn komt omdat de statistische toets een te lage kracht heeft om het verschil te detecteren wanneer er maar 5 observaties zijn per groep.
Grotere steekproef?
Wat gebeurt er als we de steekproef verhogen naar 50 observaties per groep?
# Aantal simulaties en steekproefgrootte per groep
nSim <- 10000
nSamp <- 50
# We filteren de data vooraf zodat we dit niet telkens opnieuw hoeven te doen
fem <- nhanesSub %>%
filter(Gender == "female")
mal <- nhanesSub %>%
filter(Gender == "male")
# Simulatie studie
# Om snelle functies te kunnen gebruiken nemen we eerst nSim steekproeven en berekenen we daarna alles.
femSamps <- malSamps <- matrix(NA, nrow = nSamp, ncol = nSim)
for (i in 1:nSim)
{
femSamps[,i] <- sample(fem$Height, nSamp)
malSamps[,i] <- sample(mal$Height, nSamp)
}
res <- data.frame(
verschil = colMeans(femSamps) - colMeans(malSamps),
Rfast::ttests(femSamps, malSamps)
)
sum(res$pvalue < 0.05 & res$verschil < 0)
[1] 10000
[1] 0
sum(res$pvalue < 0.05 & res$verschil > 0)
[1] 0
res %>%
ggplot(aes(x=verschil,y=-log10(pvalue),color=pvalue<0.05)) +
geom_point() +
xlab("Gemiddeld Verschil (cm)") +
ylab("Statistische Significantie (-log10 p)")

res %>%
ggplot(aes(y=verschil)) +
geom_boxplot() +
ylab("Gemiddeld Verschil (cm)")

$x
[1] ""
attr(,"class")
[1] "labels"
LS0tCnRpdGxlOiAiMS4gSW50cm9kdWN0aWU6IFdhYXJvbSBTdGF0aXN0aWVrPyIKYXV0aG9yOiAiTGlldmVuIENsZW1lbnQiCmRhdGU6ICJzdGF0T21pY3MsIEdoZW50IFVuaXZlcnNpdHkgKGh0dHBzOi8vc3RhdG9taWNzLmdpdGh1Yi5pbykiCm91dHB1dDoKICAgIGh0bWxfZG9jdW1lbnQ6CiAgICAgIGNvZGVfZG93bmxvYWQ6IHRydWUgICAgCiAgICAgIHRoZW1lOiBjb3NtbwogICAgICB0b2M6IHRydWUKICAgICAgdG9jX2Zsb2F0OiB0cnVlCiAgICAgIGhpZ2hsaWdodDogdGFuZ28KICAgICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCi0tLQoKIyBJbnRyb2R1Y3RpZQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChpbmNsdWRlID0gVFJVRSwgY29tbWVudCA9IE5BLCBlY2hvID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKYGBgCgotIFdlIGxldmVuIGluIGhldCBiaWcgZGF0YSBlcmEKLSBHZWdldmVucyBvdmVyIGxvY2F0aWUsIHN1cmZnZWRyYWcsIGFhbmtvb3BnZWRyYWcsIHNvY2lhbGUgbWVkaWEKLSBXZXRlbnNjaGFwOiBleHByZXNzaWUgbWV0ZW4gdmFuIGR1aXplbmRlbiBnZW5lbiwgZWl3aXR0ZW4sLi4uIHZvb3IgZWxrIHN1YmplY3QKLSBDaGVtaXNjaGUgcHJvY2VzIGNvbnRyb2xlOiBncm9vdCBhYW50YWwgc2Vuc29yZW4gZGllIGNvbnRpbnUgZWVuIHByb2NlcyBtZXRlbiB6b2RhdCBoZXQgcHJvY2VzIGthbiB3b3JkZW4gYmlqZ2VzdHV1cmQKLSBEYXRhIGRyaXZlbiBqb3VybmFsaXNtCi0gLi4uCgpTdGF0aXN0aWVrIGlzIGRlIHdldGVuc2NoYXAgb20gdGUgbGVyZW4gdWl0IGVtcGlyaXNjaGUgZ2VnZXZlbnMKClN0YXRpc3Rpc2NoZSBnZWxldHRlcmRoZWlkIGlzIGNydWNpYWFsIG9tIHJlc3VsdGF0ZW4gZW4gcHVibGljYXRpZXMga3JpdGlzY2ggdGUga3VubmVuIGludGVycHJldGVyZW4uCgojIyBCb3V0YWRlOiBNZXQgc3RhdGlzdGllayBrYW4gamUgYWxsZXMgYmV3aWp6ZW4KCi0tLQoKIyMgTWV0IGZvdXRlIHN0YXRpc3RpZWsga2FuIGplIGFsbGVzIGJld2lqemVuCgotLS0KCmh0dHBzOi8vd3d3Lm1lZHJ4aXYub3JnL2NvbnRlbnQvMTAuMTEwMS8yMDIwLjA3LjE3LjIwMTU1ODQ2djEKCiFbXShodHRwczovL2dpdGh1Yi5jb20vc3RhdE9taWNzL3NiYzIwL3Jhdy9tYXN0ZXIvdGhlb3J5L2ZpZ3VyZXMvRm9uc2VjYTIwMjBDb3ZpZFZlZ2V0YWJsZXMucG5nKQoKLS0tCgohW10oaHR0cHM6Ly9naXRodWIuY29tL3N0YXRPbWljcy9zYmMyMC9yYXcvbWFzdGVyL3RoZW9yeS9maWd1cmVzL2NvdmlkVmVnZXRhYmxlczYucG5nKXt3aWR0aD03MCV9CgpOb2cgbmlldCBnZXB1YmxpY2VlcmQgbWFhciBpbnR1c3NlbiBvb2sgZ2VjaXRlZXJkIGluIDQgZ2VwdWJsaWNlZXJkZSB3ZXRlbnNjaGFwcGVsaWprZSBhcnRpa2VscwoKLS0tCgohW10oaHR0cHM6Ly9naXRodWIuY29tL3N0YXRPbWljcy9zYmMyMC9yYXcvbWFzdGVyL3RoZW9yeS9maWd1cmVzL2NvdmlkVmVnZXRhYmxlcy5wbmcpe3dpZHRoPTcwJX0KCiJUaGUgYXV0aG9ycyBzdGF0ZTogVGhlIG5lZ2F0aXZlIGVjb2xvZ2ljYWwgYXNzb2NpYXRpb24gYmV0d2VlbiBDT1ZJRC0xOSBtb3J0YWxpdHkgYW5kIHRoZSBjb25zdW1wdGlvbiBvZiBjYWJiYWdlIGFuZCBjdWN1bWJlciBzdXBwb3J0cyB0aGUgYSBwcmlvcmkgaHlwb3RoZXNpcyBwcmV2aW91c2x5IHJlcG9ydGVkLgpJbiB0aGlzIGh5cG90aGVzaXMsIHdlIHByb3Bvc2VkIHRoYXQgdmVnZXRhYmxlcyBzdWNoIGFzIEJyYXNzaWNhIC0gd2l0aCBhbiBhbnRpb3hpZGFudCBhY3Rpdml0eSByZWR1Y2luZyBpbnN1bGluIHJlc2lzdGFuY2UgLSBtYXkgYWxzbyBiZSBhc3NvY2lhdGVkIHdpdGggbG93IENPVklELTE5IG1vcnRhbGl0eSBpbiBjb3VudHJpZXMuCiIKCiIKVGhvdWdoIG91ciByZXN1bHRzIGRvIG5vdCBhbGxvdyB0byBpbmZlciBjYXVzYWxpdHksIHRoZXkgZG8gcmVpbmZvcmNlIG91ciBhIHByaW9yeSBoeXBvdGhlc2lzIHRoYXQgdGhlIGluZ2VzdGlvbiBvZiBhbnRpLW94aWRhbnQgZm9vZHMgYWN0aW5nIG9uIGluc3VsaW4gaW50b2xlcmFuY2UgbWF5IGhhdmUgcmVkdWNlZCB0aGUgc2V2ZXJpdHkgb2YgQ09WSUQtMTkuCiIKCi0tLQoKIVtdKGh0dHBzOi8vZ2l0aHViLmNvbS9zdGF0T21pY3Mvc2JjMjAvcmF3L21hc3Rlci90aGVvcnkvZmlndXJlcy9jb3ZpZFZlZ2V0YWJsZXM0LnBuZykKCi0tLQoKIVtdKGh0dHBzOi8vZ2l0aHViLmNvbS9zdGF0T21pY3Mvc2JjMjAvcmF3L21hc3Rlci90aGVvcnkvZmlndXJlcy9jb3ZpZFZlZ2V0YWJsZXMzLnBuZykKCi0gVmVsZSBoeXBvdGhlc2VzIHdvcmRlbiBnZXRlc3QgPyEKLSBDYXVzYWxpdGVpdCA/IQotIEJlbGFuZyB2YW4gZXhwZXJpbWVudGVlbCBkZXNpZ246IE9ic2VydmF0aW9uZWxlIHN0dWRpZQotIE9wIGJhc2lzIHZhbiBkZSBkYXRhIHppam4gZ2VlbiB1aXRzcHJha2VuIG1vZ2VsaWprIG9wIGhldCBuaXZlYXUgdmFuIGluZGl2aWR1ZW4KCi0tLQoKIVtdKGh0dHBzOi8vZ2l0aHViLmNvbS9zdGF0T21pY3Mvc2JjMjAvcmF3L21hc3Rlci90aGVvcnkvZmlndXJlcy9jb3ZpZFZlZ2V0YWJsZXMyLnBuZyl7d2lkdGg9NzAlfQoKLSBCZWxhbmcgRGF0YSBFeHBsb3JhdGllIQotIERhdGEgdG9vbnQgbmlldCBlY2h0IGVlbiB0cmVuZAotIERhdGEgdG9vbnQgZWVyZGVyIHR3ZWUgY2x1c3RlcnM6IGJlbmVkZW4gZW4gYm92ZW4gMjAwIGRvZGVuL21pbGpvZW4KLSBNb2RlbCBvcCBiYXNpcyB2YW4ga29ta29tbWVyIGNvbnN1bXB0aWUgbW9kZWxsZWVydCBkZSBkYXRhIG5pZXQgY29ycmVjdDogb3ZlcnNjaGF0dGluZyB2b29yIGVlbiBoZWVsIGFhbnRhbCBsYW5kZW4gbWV0IGxhZ2UgY29uc3VtcHRpZSB6b2FscyBQb3J0dWdhbCwgSG9uZ2FyaWplLCBTbG92ZW5pw6ssIC4uLgoKLS0tCgotIFBhcGVycyB6aWpuIG5vZyBuaWV0IGFhbnZhYXJkIGluIGVlbiBqb3VybmFsIG1hYXIgd29yZGVuIHRvY2ggYWwgNCBrZWVyIGdlY2l0ZWVyZCBpbiBwYXBlcnMgZGllIHJlZWRzIHppam4gZ2VwdWJsaWNlZXJkIGluIHdldGVuc2NoYXBwZWxpamtlIHRpamRzY2hyaWZ0ZW4hISEKCi0tLQoKRHJpZSBncm90ZSB0YWtrZW4gaW4gc3RhdGlzdGllawoKMS4gU3RhdGlzdGlzY2hlIGluZmVyZW50aWUKCiAgLSBJcyBlciBlZW4gdmVyYmFuZCB0dXNzZW4gQ09WSUQtMTkgZW4gdm9lZHNlbGNvbnN1bXB0aWU/CiAgLSBHZXZhYXIgZGllIHdlIG9wbWVya3RlbiBpbiBzdHVkaWU6CiAgICAgIC0gZGF0YSBkcmVkZ2luZywgcC1oYWNraW5nLCAuLi46IGluIGdyb3RlIGRhdGFzZXRzIHdhYXIgamUgaGVlbCB2ZWVsIGh5cG90aGVzZXMgdGVzdCB2aW5kIGplIHZyaWp3ZWwgYWx0aWpkIHZyaWogc3RlcmtlIHBhdHJvbmVuIHZpbmRlbiBkb29yIHRvZXZhbCAkXHJpZ2h0YXJyb3ckIEplIG1vZXQgamUgYW5hbHlzZSBjb3JyaWdlcmVuIGFscyBqZSBtZWVyZGVyZSBoeXBvdGhlc2VzIHRlc3QuCiAgICAgIC0gTW9kZWwgYWFubmFtZXMgbmlldCB2b2xkYWFuCiAgICAgIC0gQ29uZm91bmRpbmcKCjIuIFN0dWRpZWRlc2lnbgoKICAgIC0gQ29uZm91bmRpbmc6IExhbmRlbiB2ZXJzY2hpbGxlbiBuaWV0IGVua2VsIGluIGNvbnN1bXB0aWUgdmFuIMOpw6luIGJlcGFhbGRlIGdyb2VudGUgbWFhciBvb2sgaW4gYW5kZXJlIHZlcmFuZGVybGlqa2VuIChkZW1vZ3JhZmllLCByZWdpc3RyYXRpZSB2YW4gY292aWQgZG9kZW4sIG1hYXRyZWdlbHMsIGdlem9uZGhlaWRzem9yay4uLikgZGllIGdlcmVsYXRlZXJkIHppam4gYWFuIENPVklELTE5IG1vcnRhbGl0ZWl0CgogICAgLSBEYWFyb20gbW9laWxpamsgb20gdWl0IG9ic2VydmF0aW9uZWxlIHN0dWRpZXMgY2F1c2FsZSAob29yemFhay1nZXZvbGcpIHZlcmJhbmRlbiB0ZSB0cmVra2VuCgogICAgLSBJbiBleHBlcmltZW50ZWxlIHN0dWRpZTogIHJhbmRvbWlzYXRpZSBvbSB0ZSB6b3JnZW4gZGF0IGdyb2VwZW4gZW5rZWwgdmVyc2NoaWxsZW4gaW4gZGUgYmVoYW5kZWxpbmcuCgogICAgLSBFeHBlcmltZW50ZWxlIHN0dWRpZXMgemlqbiBkYWFyb20gZGUgZ291ZGVuIHN0YW5kYWFyZCBvbSB0ZSB0ZXN0ZW4gdm9vciBjYXVzYWxlIHZlcmJhbmRlbi4KCjMuIERhdGEgZXhwbG9yYXRpZSBlbiB2aXN1YWxpc2F0aWUKCiAgICAtIENydWNpYWFsIG9tIGluemljaHQgdGUgdmVyd2VydmVuIGluIGRlIGRhdGEKICAgIC0gTW9kZWwgdmVyb25kZXJzdGVsbGluZ2VuIG5hZ2FhbiEKCi0tLQoKR2FyY2lhLUJlcnRob3UgJiBBbGNhcmF6IChNZWQuIFJlcy4gTWV0aC4gMjAwNCk6CgotIEphYXJnYW5nIDIwMDEgdmFuIE5hdHVyZSBlbiBCcml0aXNoIE1lZGljYWwgSm91cm5hbAotIDM4JSBlbiAyNSUgdmFuIGFydGlrZWxlbiBiZXZhdCBlZW4gc3RhdGlzdGlzY2hlIGZvdXQKLSAxMSU6IGZvdXRlbiB0ZWdlbiBpbnRlcnByZXRhdGllCi0gNCU6IGJlc2x1aXQgc3ByZWVrdCBldmlkZW50aWUgdGVnZW4KCiRccmlnaHRhcnJvdyQgU3RhdGlzdGlzY2hlIGdlbGV0dGVyZGhlaWQgaXMgY3J1Y2lhYWwgb20gcmVzdWx0YXRlbiBlbiBwdWJsaWNhdGllcyBrcml0aXNjaCBlbiBjb3JyZWN0IHRlIGt1bm5lbiBpbnRlcnByZXRlcmVuLgoKLS0tCgojIENhc2Ugc3R1ZHk6IG9rc2VsIG1pY3JvYmlvbWUKCgohW10oaHR0cHM6Ly9pbWFnZXMudnJ0LmJlL3dpZHRoMTI4MC8yMDE4LzA2LzI3LzRlNzIwOThkLTdhMGQtMTFlOC1hYmNjLTAyYjdiNzZiZjQ3Zi5qcGcpe3dpZHRoPTcwJX0KCi0gaHR0cHM6Ly93d3cudnJ0LmJlL3ZydG53cy9ubC8yMDE4LzEwLzIyL2dlem9jaHQtbWVuc2VuLW1ldC1wZW5ldHJhbnRlLWxpamZnZXVyLW9tLXByb2Jpb3Rpc2NoZS1kZW9kb3IvCi0gaHR0cHM6Ly95b3V0dS5iZS85UklGeXFMWGRWdwoKLS0tCgotIE9rc2VsZ2V1ciB3b3JkdCBuaWV0IHZlcm9vcnphYWt0IGRvb3IgaGV0IHp3ZWV0IHplbGYuIERlIGdldXIgaXMgYWZrb21zdGlnIHZhbiBzcGVjaWZpY2llayBtaWNyby1vcmdhbmlzbWVuIHZhbiBkZSBncm9lcCAqQ29yeW5lYmFjdGVyaXVtIHNwcC4qIGRpZSBoZXQgendlZXQgbWV0YWJvbGlzZXJlbi4gKlN0YXBoeWxvY29jY3VzIHNwcC4qIHppam4gZWVuIGFuZGVyZSBncm9lcCBiYWN0ZXJpw6tuIGRpZSBvb2sgYWJ1bmRhbnQgemlqbiBpbiBoZXQgbWljcm9iaW9tZSB2YW4gZGUgb2tzZWwgZGllIHp3ZWV0IG1ldGFib2xpc2VyZW4gbmFhciBtZXRhYm9saWV0ZW4gZGllIG5pZXQgc3Rpbmtlbi4KCi0gRGUgQ01FVC1ncm9lcCBhYW4gVUdFTlQgZG9ldCBvbmRlcnpvZWsgbmFhciBoZXQgdHJhbnNwbGFudGVyZW4gdmFuIGRlIG1pY3JvYmnDq2xlIGdlbWVlbnNjaGFwLCBoZXQgbWljcm9iaW9tZSwgb20gbWVuc2VuIHZhbiBnZXVyZW5kZSBva3NlbHMgYWYgdGUgaGVscGVuLiAgCgotIFZvb3JnZXN0ZWxkZSB0aGVyYXBpZQogIAkxLiBWZXJ3aWpkZXIgaGV0IG9rc2VsIG1pY3JvYmlvbWUgbWV0IGFudGliaW90aWNhCiAgICAyLiBCZcOvbnZsb2VkIGhldCBva3NlbCBtaWNyb2Jpb21lIGRvb3IgbWljcm9iaW9tZSB0ZSB0cmFuc3BsYW50ZXJlbiB2YW4gZWVuIGluZGl2aWR1ZSBkaWUgZ2VlbiBnZXVyZW5kZSBva3NlbHMgaGVlZnQgKGh0dHBzOi8veW91dHUuYmUvOVJJRnlxTFhkVncpCgoKLS0tCgojIyBQcm9lZm9wemV0IChleHBlcmltZW50YWwgZGVzaWduKQoKYGBge3Igb3V0LndpZHRoPSc4MCUnLGZpZy5hc3A9LjgsIGZpZy5hbGlnbj0nY2VudGVyJyxlY2hvPUZBTFNFfQppZiAoInBpIiVpbiVscygpKSBybSgicGkiKQprb3B2b2V0ZXI8LWZ1bmN0aW9uKHgseSxhbmdsZT0wLGw9LjIsY2V4LmRvdD0uNSxwY2g9MTksY29sPSJibGFjayIpCnsKYW5nbGU9YW5nbGUvMTgwKnBpCnBvaW50cyh4LHksY2V4PWNleC5kb3QscGNoPXBjaCxjb2w9Y29sKQpsaW5lcyhjKHgseCtsKmNvcygtcGkvMithbmdsZSkpLGMoeSx5K2wqc2luKC1waS8yK2FuZ2xlKSksY29sPWNvbCkKbGluZXMoYyh4K2wvMipjb3MoLXBpLzIrYW5nbGUpLHgrbC8yKmNvcygtcGkvMithbmdsZSkrbC80KmNvcyhhbmdsZSkpLGMoeStsLzIqc2luKC1waS8yK2FuZ2xlKSx5K2wvMipzaW4oLXBpLzIrYW5nbGUpK2wvNCpzaW4oYW5nbGUpKSxjb2w9Y29sKQpsaW5lcyhjKHgrbC8yKmNvcygtcGkvMithbmdsZSkseCtsLzIqY29zKC1waS8yK2FuZ2xlKStsLzQqY29zKHBpK2FuZ2xlKSksYyh5K2wvMipzaW4oLXBpLzIrYW5nbGUpLHkrbC8yKnNpbigtcGkvMithbmdsZSkrbC80KnNpbihwaSthbmdsZSkpLGNvbD1jb2wpCmxpbmVzKGMoeCtsKmNvcygtcGkvMithbmdsZSkseCtsKmNvcygtcGkvMithbmdsZSkrbC8yKmNvcygtcGkvMitwaS80K2FuZ2xlKSksYyh5K2wqc2luKC1waS8yK2FuZ2xlKSx5K2wqc2luKC1waS8yK2FuZ2xlKStsLzIqc2luKC1waS8yK3BpLzQrYW5nbGUpKSxjb2w9Y29sKQpsaW5lcyhjKHgrbCpjb3MoLXBpLzIrYW5nbGUpLHgrbCpjb3MoLXBpLzIrYW5nbGUpK2wvMipjb3MoLXBpLzItcGkvNCthbmdsZSkpLGMoeStsKnNpbigtcGkvMithbmdsZSkseStsKnNpbigtcGkvMithbmdsZSkrbC8yKnNpbigtcGkvMi1waS80K2FuZ2xlKSksY29sPWNvbCkKfQoKcGFyKG1hcj1jKDAsMCwwLDApLG1haT1jKDAsMCwwLDApKQpwbG90KDAsMCx4bGFiPSIiLHlsYWI9IiIseGxpbT1jKDAsMTApLHlsaW09YygwLDEwKSxjb2w9MCx4YXh0PSJub25lIix5YXh0PSJub25lIixheGVzPUZBTFNFKQpyZWN0KDAsNiwxMCwxMCxib3JkZXI9InJlZCIsbHdkPTIpCnRleHQoLjUsOCwicG9wdWxhdGlvbiIsc3J0PTkwLGNvbD0icmVkIixjZXg9MikKc3ltYm9scyAoMywgOCwgY2lyY2xlcz0xLjUsIGNvbD0icmVkIixhZGQ9VFJVRSxmZz0icmVkIixpbmNoZXM9RkFMU0UsbHdkPTIpCnNldC5zZWVkKDMzMCkKZ3JpZD1zZXEoMCwxLjMsLjAxKQoKZm9yIChpIGluIDE6NTApCnsKCWFuZ2xlMT1ydW5pZihuPTEsbWluPTAsbWF4PTM2MCkKCWFuZ2xlMj1ydW5pZihuPTEsbWluPTAsbWF4PTM2MCkKCXJhZGl1cz1zYW1wbGUoZ3JpZCxwcm9iPWdyaWReMipwaS9zdW0oZ3JpZF4yKnBpKSxzaXplPTEpCglrb3B2b2V0ZXIoMytyYWRpdXMqY29zKGFuZ2xlMS8xODAqcGkpLDgrcmFkaXVzKnNpbihhbmdsZTEvMTgwKnBpKSxhbmdsZT1hbmdsZTIpCn0KdGV4dCg3LjUsOCwiTWljcm9iaW9tZSBpbiBwb3B1bGF0aW9uIixjb2w9InJlZCIsY2V4PTEuMikKYGBgCgotLS0KCgpgYGB7ciBvdXQud2lkdGg9JzgwJScsZmlnLmFzcD0uOCwgZmlnLmFsaWduPSdjZW50ZXInLGVjaG89RkFMU0V9CmlmICgicGkiJWluJWxzKCkpIHJtKCJwaSIpCmtvcHZvZXRlcjwtZnVuY3Rpb24oeCx5LGFuZ2xlPTAsbD0uMixjZXguZG90PS41LHBjaD0xOSxjb2w9ImJsYWNrIikKewphbmdsZT1hbmdsZS8xODAqcGkKcG9pbnRzKHgseSxjZXg9Y2V4LmRvdCxwY2g9cGNoLGNvbD1jb2wpCmxpbmVzKGMoeCx4K2wqY29zKC1waS8yK2FuZ2xlKSksYyh5LHkrbCpzaW4oLXBpLzIrYW5nbGUpKSxjb2w9Y29sKQpsaW5lcyhjKHgrbC8yKmNvcygtcGkvMithbmdsZSkseCtsLzIqY29zKC1waS8yK2FuZ2xlKStsLzQqY29zKGFuZ2xlKSksYyh5K2wvMipzaW4oLXBpLzIrYW5nbGUpLHkrbC8yKnNpbigtcGkvMithbmdsZSkrbC80KnNpbihhbmdsZSkpLGNvbD1jb2wpCmxpbmVzKGMoeCtsLzIqY29zKC1waS8yK2FuZ2xlKSx4K2wvMipjb3MoLXBpLzIrYW5nbGUpK2wvNCpjb3MocGkrYW5nbGUpKSxjKHkrbC8yKnNpbigtcGkvMithbmdsZSkseStsLzIqc2luKC1waS8yK2FuZ2xlKStsLzQqc2luKHBpK2FuZ2xlKSksY29sPWNvbCkKbGluZXMoYyh4K2wqY29zKC1waS8yK2FuZ2xlKSx4K2wqY29zKC1waS8yK2FuZ2xlKStsLzIqY29zKC1waS8yK3BpLzQrYW5nbGUpKSxjKHkrbCpzaW4oLXBpLzIrYW5nbGUpLHkrbCpzaW4oLXBpLzIrYW5nbGUpK2wvMipzaW4oLXBpLzIrcGkvNCthbmdsZSkpLGNvbD1jb2wpCmxpbmVzKGMoeCtsKmNvcygtcGkvMithbmdsZSkseCtsKmNvcygtcGkvMithbmdsZSkrbC8yKmNvcygtcGkvMi1waS80K2FuZ2xlKSksYyh5K2wqc2luKC1waS8yK2FuZ2xlKSx5K2wqc2luKC1waS8yK2FuZ2xlKStsLzIqc2luKC1waS8yLXBpLzQrYW5nbGUpKSxjb2w9Y29sKQp9CgpwYXIobWFyPWMoMCwwLDAsMCksbWFpPWMoMCwwLDAsMCkpCnBsb3QoMCwwLHhsYWI9IiIseWxhYj0iIix4bGltPWMoMCwxMCkseWxpbT1jKDAsMTApLGNvbD0wLHhheHQ9Im5vbmUiLHlheHQ9Im5vbmUiLGF4ZXM9RkFMU0UpCnJlY3QoMCw2LDEwLDEwLGJvcmRlcj0icmVkIixsd2Q9MikKdGV4dCguNSw4LCJwb3B1bGF0aW9uIixzcnQ9OTAsY29sPSJyZWQiLGNleD0yKQpzeW1ib2xzICgzLCA4LCBjaXJjbGVzPTEuNSwgY29sPSJyZWQiLGFkZD1UUlVFLGZnPSJyZWQiLGluY2hlcz1GQUxTRSxsd2Q9MikKc2V0LnNlZWQoMzMwKQpncmlkPXNlcSgwLDEuMywuMDEpCgpmb3IgKGkgaW4gMTo1MCkKewoJYW5nbGUxPXJ1bmlmKG49MSxtaW49MCxtYXg9MzYwKQoJYW5nbGUyPXJ1bmlmKG49MSxtaW49MCxtYXg9MzYwKQoJcmFkaXVzPXNhbXBsZShncmlkLHByb2I9Z3JpZF4yKnBpL3N1bShncmlkXjIqcGkpLHNpemU9MSkKCWtvcHZvZXRlcigzK3JhZGl1cypjb3MoYW5nbGUxLzE4MCpwaSksOCtyYWRpdXMqc2luKGFuZ2xlMS8xODAqcGkpLGFuZ2xlPWFuZ2xlMikKfQp0ZXh0KDcuNSw4LCJNaWNyb2Jpb21lIGluIHBvcHVsYXRpb24iLGNvbD0icmVkIixjZXg9MS4yKQoKcmVjdCgwLDAsMTAsNCxib3JkZXI9ImJsdWUiLGx3ZD0yKQp0ZXh0KC41LDIsInNhbXBsZSIsc3J0PTkwLGNvbD0iYmx1ZSIsY2V4PTIpCnN5bWJvbHMgKDMsIDIsIGNpcmNsZXM9MS41LCBjb2w9InJlZCIsYWRkPVRSVUUsZmc9ImJsdWUiLGluY2hlcz1GQUxTRSxsd2Q9MikKZm9yIChpIGluIDA6MSkKCWZvciAoaiBpbiAwOjQpCnsKCglrb3B2b2V0ZXIoMi4xK2oqKDMuOS0yLjEpLzQsMS4xK2kvMixjb2w9ImJsYWNrIikKfQpmb3IgKGkgaW4gMjozKQoJZm9yIChqIGluIDA6NCkKewoKCWtvcHZvZXRlcigyLjEraiooMy45LTIuMSkvNCwxLjYraS8yLGNvbD0iYmxhY2siKQp9CnRleHQoNy41LDIsIk1pY3JvYmlvbWUgaW4gc2FtcGxlIixjb2w9ImJsdWUiLGNleD0xLjIpCgphcnJvd3MoMyw1LjksMyw0LjEsY29sPSJibGFjayIsbHdkPTMpCnRleHQoMS41LDUsIkVYUC4gREVTSUdOICgxKSIsY29sPSJibGFjayIsY2V4PTEuMikKYGBgCgotLS0KCi0gRXhwZXJpbWVudDoKCiAgICAtIDIwIHBlcnNvbmVuIHdvcmRlbiBhdCByYW5kb20gdWl0IGRlIHBvcHVsYXRpZSBnZXRyb2trZW4gdmFuIHBlcnNvbmVuIG1ldCBlZW4gb2tzZWxnZXVyOiBzdGVla3Byb2VmIHJlcHJlc2VudGF0aWVmIHZvb3IgcG9wdWxhdGllIQoKICAgIC0gZGUgcGVyc29uZW4gd29yZGVuIGF0IHJhbmRvbSB2ZXJkZWVsZCBvdmVyIHR3ZWUgYmVoYW5kZWxpbmdzZ3JvZXBlbjoKCiAgICAgICAgLSBwbGFjZWJvIChlbmtlbCBhbnRpYmlvdGljYSkKICAgICAgICAtIHRyYW5zcGxhbnRpZSAoYW50aWJpb3RpY2EgZW4gbWljcm9iacOrbGUgdHJhbnNwbGFudGF0aWUpLgogICAgICAgIC0gUmFuZG9taXNhdGllIGlzIGJlbGFuZ3Jpamsgb20gZXJ2b29yIHRlIHpvcmdlbiBkYXQgZGUgZ3JvZXBlbiB2ZXJnZWxpamtiYWFyIHppam4uCgogICAgLSBIZXQgbWljcm9iaW9tZSB3b3JkdCBiZW1vbnN0ZXJkIDYgd2VrZW4gbmEgZGUgYmVoYW5kZWxpbmcuCiAgICAtIFRoZSByZWxhdGl2ZSBhYnVuZGFudGllIHZhbiAqU3RhcGh5bG9jb2NjdXMgc3BwLiogb3AgKkNvcnluZWJhY3Rlcml1bSBzcHAuKiArICpTdGFwaHlsb2NvY2N1cyBzcHAuKiBpbiBoZXQgbWljcm9iaW9tZSB3b3JkdCBnZW1ldGVuIHZpYSBER0dFICgqRGVuYXR1cmluZyBHcmFkaWVudCBHZWwgRWxlY3Ryb3Bob3Jlc2lzKikuCgotLS0KCkRHR0UKCiFbXShodHRwczovL2pvdXJuYWxzLnBsb3Mub3JnL3Bsb3NvbmUvYXJ0aWNsZS9maWd1cmUvaW1hZ2U/c2l6ZT1sYXJnZSZkb3dubG9hZD0maWQ9MTAuMTM3MS9qb3VybmFsLnBvbmUuMDA3MDUzOC5nMDAxKXt3aWR0aD03MCV9CgpodHRwczovL2RvaS5vcmcvMTAuMTM3MS9qb3VybmFsLnBvbmUuMDA3MDUzOAoKLS0tCgpWZXJ0YWFsIG9uZGVyem9la3N2cmFhZyBuYWFyIGlldHMgd2F0IHdlIGt1bm5lbiBxdWFudGlmaWNlcmVuOiBJcyBlciBlZW4gdmVyc2NoaWwgaW4gcmVsYXRpZXZlIGFidW5kYW50aWUgdmFuICpTdGFwaHlsb2NvY2N1cyBzcHAuKiBpbiBoZXQgbWljcm9iaW9tZSB2YW4gZGUgcGxhY2VibyBncm9lcCBlbiBkZSB0cmFuc3BsYW50YXRpZQoKLS0tCgpgYGB7ciBvdXQud2lkdGg9JzgwJScsZmlnLmFzcD0uOCwgZmlnLmFsaWduPSdjZW50ZXInLGVjaG89RkFMU0V9CmlmICgicGkiJWluJWxzKCkpIHJtKCJwaSIpCmtvcHZvZXRlcjwtZnVuY3Rpb24oeCx5LGFuZ2xlPTAsbD0uMixjZXguZG90PS41LHBjaD0xOSxjb2w9ImJsYWNrIikKewphbmdsZT1hbmdsZS8xODAqcGkKcG9pbnRzKHgseSxjZXg9Y2V4LmRvdCxwY2g9cGNoLGNvbD1jb2wpCmxpbmVzKGMoeCx4K2wqY29zKC1waS8yK2FuZ2xlKSksYyh5LHkrbCpzaW4oLXBpLzIrYW5nbGUpKSxjb2w9Y29sKQpsaW5lcyhjKHgrbC8yKmNvcygtcGkvMithbmdsZSkseCtsLzIqY29zKC1waS8yK2FuZ2xlKStsLzQqY29zKGFuZ2xlKSksYyh5K2wvMipzaW4oLXBpLzIrYW5nbGUpLHkrbC8yKnNpbigtcGkvMithbmdsZSkrbC80KnNpbihhbmdsZSkpLGNvbD1jb2wpCmxpbmVzKGMoeCtsLzIqY29zKC1waS8yK2FuZ2xlKSx4K2wvMipjb3MoLXBpLzIrYW5nbGUpK2wvNCpjb3MocGkrYW5nbGUpKSxjKHkrbC8yKnNpbigtcGkvMithbmdsZSkseStsLzIqc2luKC1waS8yK2FuZ2xlKStsLzQqc2luKHBpK2FuZ2xlKSksY29sPWNvbCkKbGluZXMoYyh4K2wqY29zKC1waS8yK2FuZ2xlKSx4K2wqY29zKC1waS8yK2FuZ2xlKStsLzIqY29zKC1waS8yK3BpLzQrYW5nbGUpKSxjKHkrbCpzaW4oLXBpLzIrYW5nbGUpLHkrbCpzaW4oLXBpLzIrYW5nbGUpK2wvMipzaW4oLXBpLzIrcGkvNCthbmdsZSkpLGNvbD1jb2wpCmxpbmVzKGMoeCtsKmNvcygtcGkvMithbmdsZSkseCtsKmNvcygtcGkvMithbmdsZSkrbC8yKmNvcygtcGkvMi1waS80K2FuZ2xlKSksYyh5K2wqc2luKC1waS8yK2FuZ2xlKSx5K2wqc2luKC1waS8yK2FuZ2xlKStsLzIqc2luKC1waS8yLXBpLzQrYW5nbGUpKSxjb2w9Y29sKQp9CgpwYXIobWFyPWMoMCwwLDAsMCksbWFpPWMoMCwwLDAsMCkpCnBsb3QoMCwwLHhsYWI9IiIseWxhYj0iIix4bGltPWMoMCwxMCkseWxpbT1jKDAsMTApLGNvbD0wLHhheHQ9Im5vbmUiLHlheHQ9Im5vbmUiLGF4ZXM9RkFMU0UpCnJlY3QoMCw2LDEwLDEwLGJvcmRlcj0icmVkIixsd2Q9MikKdGV4dCguNSw4LCJwb3B1bGF0aW9uIixzcnQ9OTAsY29sPSJyZWQiLGNleD0yKQpzeW1ib2xzICgzLCA4LCBjaXJjbGVzPTEuNSwgY29sPSJyZWQiLGFkZD1UUlVFLGZnPSJyZWQiLGluY2hlcz1GQUxTRSxsd2Q9MikKc2V0LnNlZWQoMzMwKQpncmlkPXNlcSgwLDEuMywuMDEpCgpmb3IgKGkgaW4gMTo1MCkKewoJYW5nbGUxPXJ1bmlmKG49MSxtaW49MCxtYXg9MzYwKQoJYW5nbGUyPXJ1bmlmKG49MSxtaW49MCxtYXg9MzYwKQoJcmFkaXVzPXNhbXBsZShncmlkLHByb2I9Z3JpZF4yKnBpL3N1bShncmlkXjIqcGkpLHNpemU9MSkKCWtvcHZvZXRlcigzK3JhZGl1cypjb3MoYW5nbGUxLzE4MCpwaSksOCtyYWRpdXMqc2luKGFuZ2xlMS8xODAqcGkpLGFuZ2xlPWFuZ2xlMikKfQp0ZXh0KDcuNSw4LCJNaWNyb2Jpb21lIGluIHBvcHVsYXRpb24iLGNvbD0icmVkIixjZXg9MS4yKQoKcmVjdCgwLDAsMTAsNCxib3JkZXI9ImJsdWUiLGx3ZD0yKQp0ZXh0KC41LDIsInNhbXBsZSIsc3J0PTkwLGNvbD0iYmx1ZSIsY2V4PTIpCnN5bWJvbHMgKDMsIDIsIGNpcmNsZXM9MS41LCBjb2w9InJlZCIsYWRkPVRSVUUsZmc9ImJsdWUiLGluY2hlcz1GQUxTRSxsd2Q9MikKZm9yIChpIGluIDA6MSkKCWZvciAoaiBpbiAwOjQpCnsKCglrb3B2b2V0ZXIoMi4xK2oqKDMuOS0yLjEpLzQsMS4xK2kvMixjb2w9InB1cnBsZSIpCn0KZm9yIChpIGluIDI6MykKCWZvciAoaiBpbiAwOjQpCnsKCglrb3B2b2V0ZXIoMi4xK2oqKDMuOS0yLjEpLzQsMS42K2kvMixjb2w9Im9yYW5nZSIpCn0KdGV4dCg3LjUsMiwiTWljcm9iaW9tZSBpbiBzYW1wbGUiLGNvbD0iYmx1ZSIsY2V4PTEuMikKCmFycm93cygzLDUuOSwzLDQuMSxjb2w9ImJsYWNrIixsd2Q9MykKdGV4dCgxLjUsNSwiRVhQLiBERVNJR04gKDEpIixjb2w9ImJsYWNrIixjZXg9MS4yKQp0ZXh0KDcuNSwuNSwiREFUQSBFWFBMT1JBVElPTiAmXG5ERVNDUklQVElWRSBTVEFUSVNUSUNTICgyKSIsY29sPSJibGFjayIsY2V4PTEuMikKYGBgCgotLS0KCiMjIERhdGEgRXhwbG9yYXRpZSBlbiBiZXNjaHJpanZlbmRlIHN0YXRpc3RpZWsKCgotIERhdGEgZXhwbG9yYXRpZSBpcyBoZWVsIGJlbGFuZ3Jpamsgb20gaW56aWNodCB0ZSBrcmlqZ2VuIGluIGRlIGRhdGEgZW4gaXMgZWVuIGVzc2VudGnDq2xlIGVlcnN0ZSBzdGFwIG9tIHRlIGxlcmVuIHVpdCBkYXRhLgotIEhldCB3b3JkdCB2YWFrIG9uZGVyZ2V3YWFyZGVlcmQgb2Ygb3ZlciBoZXQgaG9vZmQgZ2V6aWVuLgoKLS0tCgojIyMgSW1wb3J0ZWVyIGRlIGRhdGEKCi0gRGF0YSBpbiBkZXplIGN1cnN1cyB3b3JkdCB2ZXJ3ZXJrdCB2aWEgaGV0IHN0YXRpc3Rpc2NoIHNvZnR3YXJlIHBha2tldCBSLgotIERpdCBwYWtrZXQgbGFhdCB0b2Ugb20gdGUgbGVyZW4gdWl0IGRhdGEuCi0gSW4gZGV6ZSBjdXJzdXMgZ2FhbiB3ZSBkYXRhIGVlcnN0IGV4cGxvcmVyZW4gb20gaW56aWNodCB0ZSB2ZXJ3ZXJ2ZW4gaW4gZGUgZ2VnZXZlbnMgb20gZGllIHZlcnZvbGdlbnMgc3RhdGlzdGlzY2ggdGUgdmVyd2Vya2VuLgotIFZvb3JhbGVlciB3ZSBoaWVybWVlIHZhbiBzdGFydCBrdW5uZW4gZ2FhbiBtb2V0ZW4gd2UgZGUgZGF0YSBlZXJzdCBpbXBvcnRlcmVuIGluIFIuCgotIFZpYSBoZXQgdm9sZ2VuZGUgY29tbWFuZG8ga3VubmVuIHdlIGVua2VsZSByZWdlbHMgdmFuIGVlbiBkYXRhIGJlc3RhbmQgaW5sZXplbiBvbSBkZSBzdHJ1Y3R1dXIgdmFuIGhldCBkYXRhIGJlc3RhbmQgdGUgd2V0ZW4gdGUga29tZW4uCgpgYGB7cn0KcmVhZF9saW5lcygiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3N0YXRPbWljcy9zYmMyMC9tYXN0ZXIvZGF0YS9hcm1waXQuY3N2IikKYGBgCgotIEdlZ2V2ZW5zIGluIGhldCBiZXN0YW5kIHppam4gZG9vciBjb21tYSdzIGdlc2NoZWlkZW4uCi0gRWxrZSByaWogYmV2YXQgZGUgZ2VnZXZlbnMgdm9vciAxIHByb2VmcGVyc29vbgotIFZlcnNjaGlsbGVuZGUgdmFyaWFiZWxlbiB3b3JkZW4gZ2VtZXRlbiBwZXIgcGVyc29vbiBlbiB6aWpuIHZhbiBlbGthYXIgZ2VzY2hlaWRlbiBkb29yIGVlbiBjb21tYS4gSGV0IGJlc3RhbmQgaXMgY3N2IGZvcm1hYXQ6ICJjb21tYSBzZXBhcmF0ZWQgdmFsdWVzIi4KLSBXZSBrdW5uZW4gYmVzdGFuZGVuIG1ldCBkaXQgZm9ybWFhdCBpbmxlemVuIFIgdmlhIGhldCBjb21tYW5kbyByZWFkX2Nzdi4KLSBXZSBzbGFhbiBkZSBkYXRhIG9wIGluIFIgaW4gaGV0IG9iamVjdCBtZXQgbmFhbSBhcC4gSGllcnZvb3IgZ2VicnVpa2VuIHdlIGRlIGA8LWAgb3BlcmF0b3IuCi0gV2UgZ2V2ZW4gZGUgZGF0YSB0YWJlbCB0ZXJ1ZyBkb29yIGhldCBvYmplY3QgYWFuIHRlIHJvZXBlbiBkb29yIHppam4gbmFhbSB0ZSB0eXBlbi4KCmBgYHtyfQphcCA8LSByZWFkX2NzdigiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3N0YXRPbWljcy9zYmMyMC9tYXN0ZXIvZGF0YS9hcm1waXQuY3N2IikKYXAKYGBgCgotLS0KCiMjIyBCZXNjaHJpanZlbmRlIHN0YXRpc3RpZWsKCi0gSW4gYXJ0aWtlbHMgZW4gZGUgbWVkaWEgd29yZGVuIHJlc3VsdGF0ZW4gdWl0IGVlbiBzdGVla3Byb2VmIHZhYWsgZ2VyYXBwb3J0ZWVyZCBhLmQuaC52LiBnZW1pZGRlbGRlIGVuIGRlIHN0YW5kYWFyZGFmd2lqa2luZwoKLSBXZSB2YXR0ZW4gZGUgZGF0YSBlZXJzdCBzYW1lbi4gV2UgYmVyZWtlbmVuIGhldCBnZW1pZGRlbGRlIGVuIGRlIHN0YW5kYWFyZCBkZXZpYXRpZSAoZWVuIG1hYXQgdm9vciBkZSBzcHJlaWRpbmcsIHppZSB2b2xnZW5kZSBob29mZHN0dWtrZW4pLgpXZSBzbGFhbiBoZXQgcmVzdWx0YWF0IGhpZXJ2YW4gb3AgaW4gaGV0IG9iamVjdCBhcFJlbFN1bSB2aWEgYGFwUmVsU3VtIDwtYC4KCjEuIFdlIHBpcGVuICh2aWEgYCU+JWApIGhldCBgYXBgIGRhdGFmcmFtZSBuYWFyIGRlIGBncm91cF9ieWAgZnVuY3RpZSBvbSBkZSBkYXRhIHRlIGdyb2VwZXJlbiBwZXIgdHJlYXRtZW50IHRydDogYGdyb3VwX2J5KHRydClgLgoKMi4gV2UgcGlwZW4gaGV0IHJlc3VsdGFhdCBuYWFyIGRlIGBzdW1tYXJpemVfYXRgIGZ1bmN0aW9uIG9tIGRlICJyZWwiIHZhcmlhYmxlIHNhbWVuIHRlIHZhdHRlbiBlbiBiZXJla2VuZW4gaGllcmJpaiBoZXQgZ2VtaWRkZWxkZSBlbiBzdGFuZGFhcmRhZndpamtpbmcuIE9tZGF0IHdlIGRlIGRhdGEgZWVyc3QgaGViYmVuIGdlZ3JvZXBlZXJkIHp1bGxlbiB3ZSBoZXQgZ2VtaWRkZWxkZSBlbiBkZSBzdGFuZGFhcmQgZGV2aWF0aWUgYmVyZWtlbmVuIHBlciBncm9lcC4KCgoKYGBge3J9CmFwUmVsU3VtIDwtIGFwICU+JQogIGdyb3VwX2J5KHRydCkgJT4lCiAgc3VtbWFyaXplX2F0KCJyZWwiLAogICAgICAgICAgICAgICBsaXN0KG1lYW49bWVhbiwKICAgICAgICAgICAgICAgICAgICBzZD1zZAogICAgICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgICAgICkKYGBgCgpXZSB0b25lbiB2ZXJ2b2xnZW5zIGhldCByZXN1bHRhYXQgZG9vciBoZXQgb2JqZWN0IGFwUmVsU3VtIGFhbiB0ZSByb2VwZW4KCmBgYHtyfQphcFJlbFN1bQpgYGAKCldlIGt1bm5lbiBvb2sgZWVuIHRhYmVsIGluIGRlIHdlYnBhZ2luYSBvZiBoZXQgcGRmIGJlc3RhbmQgaW50ZWdyZXJlbiB2aWEgaGV0IGNvbW1hbmRvIGthYmxlIHZhbiBoZXQga25pdHIgcGFra2V0OgoKYGBge3J9CmtuaXRyOjprYWJsZShhcFJlbFN1bSkKYGBgCgotLS0KCiMjIyBHcmFmaWVrZW4KCldlIG1ha2VuIGluIGRlemUgY3Vyc3VzIGdlYnJ1aWsgdmFuIGhldCBwYWtrZXQgYGdncGxvdDJgIG9tIGdyYWZpZWtlbiB0ZSBtYWtlbi4gIApNZXQgZGUgZ2dwbG90MiBiaWJsaW90aGVlayBrdW5uZW4gd2UgZ2VtYWtrZWxpamsgZ3JhZmlla2VuIG9wYm91d2VuIGluIGxhZ2VuIChsYXllcnMpLgpIaWVyZG9vciBsZWVzdCBkZSBjb2RlIHZlZWwgbWFra2VsaWprZXIuCgojIyMjIGJhcnBsb3QKCkJhciBwbG90cyB3b3JkZW4gaGVlbCB2ZWVsIGdlYnJ1aWt0IGluIGFydGlrZWxzIG9tIHJlc3VsdGF0ZW4gd2VlciB0ZSBnZXZlbi4KCjEuIFdlIHBpcGVuIGRlIHNhbWVuZ2V2YXR0ZSBkYXRhIG5hYXIgZGUgZnVuY3RpZSBgZ2dwbG90YC4gRGF0IGlzIGRlIGJhc2lzIHZhbiBlbGtlIGdncGxvdC4gIFdlIHNlbGVjdGVyZW4gZGUgdmFyaWFiZWxlIG1ldCBkZSBiZWhhbmRlbGluZyB0cnQgYWxzIHggdmFyaWFiZWxlIGVuIGRlIHZhcmlhYmVsZSBtZXQgbmFhbSBtZWFuIGFscyB5LXZhcmlhYmVsZSB2b29yIGRlIHBsb3QuCldlIGRvZW4gZGl0IHN0ZWVkcyB2aWEgZGUgYWVzdGV0aWNzIGBhZXNgIGZ1bmN0aWUuICAgYGFlcyh4PXRydCx5PW1lYW4pYAoKMi4gV2UgbWFrZW4gZWVuIGJhcnBsb3QgZG9vciBlZW4gbGFhZyB0b2UgdGUgdm9lZ2VuIHZpYSBkZSAgYGdlb21fYmFyYCBmdW5jdGlvbi4gRGUgc3RhdGlzdGllayBpcyBgc3RhdD0iaWRlbnRpdHkiYCBvbWRhdCBkZSBob29ndGUgdmFuIGRlIGJhciBnZWxpamsgaXMgYWFuIGRlIHdhYXJkZSB2b29yIHkgKGhpZXIgaGV0IGdlbWlkZGVsZGUgdm9vciBkZSByZWxhdGlldmUgYWJ1bmRhbnRpZSkuCgozLiBXZSB2b2VnZW4gZm91dGVudmxhZ2dlbiB0b2Ugb20gZGUgb256ZWtlcmhlaWQgb3AgaGV0IGdlbWlkZGVsZGUgd2VlciB0ZSBnZXZlbi4gIFdlIGRvZW4gZGl0IHZpYSBkZSBgZ2VvbV9lcnJvcmJhcmAgZnVuY3RpZSBlbiBzcGVjaWZpw6tyZW4gaGV0IG1pbmltdW0gZW4gbWF4aW11bSB2YW4gZGUgZXJyb3IgYmFyLiBIZXQgYHdpZHRoYCBhcmd1bWVudCB3b3JkdCBnZWJydWlrdCBvbSBkZSBicmVlZHRlIHZhbiBkZSBlcnJvciBiYXIgc21hbGxlciB0ZSBtYWtlbiBkYXQgZGV6ZSB2YW4gZGUgYmFyLgoKYGBge3J9CmFwUmVsU3VtICU+JQogIGdncGxvdChhZXMoeD10cnQseT1tZWFuKSkgKwogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49bWVhbi1zZCx5bWF4PW1lYW4rc2QpLHdpZHRoPS4yKQpgYGAKCi0gSXMgZGV6ZSBwbG90IGluZm9ybWF0aWVmPz8KCi0tLQoKIyMjIyBib3hwbG90cwoKQmFycGxvdHMgemlqbiBnZWVuIGdvZWRlIGdyYWZpZWtlbjoKCi0gWmUgemlqbiBuaWV0IGluZm9ybWF0aWVmCgotIFplIHZpc3VsYXJpc2VyZW4gZWVuIHNhbWVudmF0dGluZyB2YW4gZGUgZGF0YSBkb29yIHR3ZWUgcHVudGVuOiBgdHdvIHBvaW50IHN1bW1hcnlgOiBnZW1pZGRlbGRlIGVuIGRlIHN0YW5kYWFyZCBkZXZpYXRpZSBoaWVyb3AgZW4ga3VubmVuIGJldGVyIGluIGVlbiB0YWJlbCB3b3JkZW4gb3BnZW5vbWVuLgoKLSBaZSBsYXRlbiBuaWV0IHRvZSBvbSBhbm9tYWxpZcOrbiBpbiBkZSBkYXRhIHpvYWxzIG1lZXRmb3V0ZW4gb3AgdGUgc3BvcmVuLgoKLSBaZSB2ZXJicnVpa2VuIHZlZWwgcnVpbXRlLCBiLnYuIHZhbiBudWwgdG90IGRlIGtsZWluc3RlIHdhYXJkZSB2b29yIGRlIHJlbGF0aWV2ZSBhYnVuZGFudGllKSB3YWFyIGdlZW4gZGF0YSBpbiBsaWd0LgoKSGV0IGlzIGJldGVyIG9tIGRlIGRhdGEgem8gcnV3IG1vZ2VsaWprIHZvb3IgdGUgc3RlbGxlbiB6b2RhdCB3ZSBpbnppY2h0IGtyaWpnZW4gaW4gZGUgdmVyZGVsaW5nIHZhbiBkZSBnZWdldmVucy4KSGllcnZvb3IgenVsbGVuIHdlIG9uZGVybWVlciBib3hwbG90cyBnZWJydWlrZW4uCgotLS0KCiMjIyMgQm94cGxvdHMKCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJyxlY2hvPUZBTFNFfQpmZW0gPC0gTkhBTkVTOjpOSEFORVMgJT4lIGZpbHRlcihHZW5kZXI9PSJmZW1hbGUiICYgIWlzLm5hKEhlaWdodCkgJiBBZ2U+MTgpICU+JSBzZWxlY3QoSGVpZ2h0KQpib3hwbG90KGZlbSRIZWlnaHQsIHlsYWI9Imxlbmd0ZSAoY20pIixjZXgubGFiPTEuNSxjZXguYXhpcz0xLjUsY2V4Lm1haW49MS41KQpyYW5nZUw8LXF1YW50aWxlKGZlbSRIZWlnaHQsYyguMjUsLjc1KSkrYygtMSwxKSpkaWZmKHF1YW50aWxlKGZlbSRIZWlnaHQsYyguMjUsLjc1KSkpKjEuNQpib3hZczwtYyhyYW5nZUxbMV0rKG1pbihmZW0kSGVpZ2h0KS1yYW5nZUxbMV0pLzIscmFuZ2UoZmVtJEhlaWdodFtmZW0kSGVpZ2h0PD1yYW5nZUxbMl0mZmVtJEhlaWdodD49cmFuZ2VMWzFdXSkscXVhbnRpbGUoZmVtJEhlaWdodCxjKC4yNSwuNSwuNzUpKSxyYW5nZUxbMl0rKG1heChmZW0kSGVpZ2h0KS1yYW5nZUxbMl0pLzIpCnRleHQoYygwLjUscmVwKDEuMyw1KSwwLjUpLGJveFlzLGxhYmVscz1jKCJvdXRsaWVycyIsIndpc2tlciIsIndpc2tlciIsIngyNSIsIm1lZGlhYW4iLCJ4NzUiLCJvdXRsaWVycyIpLHBvcz00LGNleD0xLjMpCmxpbmVzKGMoMC45LC43LDAuNywwLjkpLGMocmFuZ2VMWzJdLHJhbmdlTFsyXSsobWF4KGZlbSRIZWlnaHQpLXJhbmdlTFsyXSkvMixyYW5nZUxbMl0rKG1heChmZW0kSGVpZ2h0KS1yYW5nZUxbMl0pLzIsbWF4KGZlbSRIZWlnaHQpKSxsdHk9MikKbGluZXMoYygwLjksLjcsMC43LDAuOSksYyhyYW5nZUxbMV0scmFuZ2VMWzFdKyhtaW4oZmVtJEhlaWdodCktcmFuZ2VMWzFdKS8yLHJhbmdlTFsxXSsobWluKGZlbSRIZWlnaHQpLXJhbmdlTFsxXSkvMixtaW4oZmVtJEhlaWdodCkpLGx0eT0yKQpgYGAKCi0tLQoKV2UgbWFrZW4gbnUgZWVuIGJveHBsb3Qgdm9vciBkZSBhcCBkYXRhCgoxLiBXZSBwaXBlbiBoZXQgYGFwYCBkYXRhZnJhbWUgbmFhciBgZ2dwbG90YAoyLiBXZSBzZWxlY3RlcmVuIGRlIGRhdGEgdm9vciBkZSBwbG90IHZpYSBgZ2dwbG90KGFlcyh4PXRydCx5PXJlbCkpYAozLiBXZSB2b2VnZW4gbGFhZyB0b2Ugdm9vciBkZSBib3hwbG90IGRtdiBkZSBmdW5jdGllIGBnZW9tX2JveHBsb3QoKWAKCmBgYHtyfQphcCAlPiUgIAogIGdncGxvdChhZXMoeD10cnQseT1yZWwpKSArCiAgZ2VvbV9ib3hwbG90KCkKYGBgCgoKLS0tCgpNZXJrIG9wIGRhdCB3ZSBkZSBwbG90IG9vayBvcCBrdW5uZW4gc2xhYW4gYWxzIGVlbiBvYmplY3QuCgpgYGB7cn0KYXBCb3hwbG90IDwtIGFwICU+JSAgCiAgZ2dwbG90KGFlcyh4PXRydCx5PXJlbCkpICsKICBnZW9tX2JveHBsb3QoKQpgYGAKCkRlIHBsb3Qgd29yZHQgZGFuIG5pZXQgZ2VtYWFrdC4KCk9tIGRlIHBsb3Qgd2VlciB0ZSBnZXZlbiBrdW5uZW4gd2UgaGV0IG9iamVjdCBhYW5yb2VwZW4KCmBgYHtyfQphcEJveHBsb3QKYGBgCgotLS0KCi0gTWVyayBvcCBkYXQgd2UgbmlldCB6b3ZlZWwgZ2VnZXZlbnMgaGViYmVuLiBFbmtlbCAxMCBwZXIgZ3JvZXAuCgotIEhldCBpcyBhbHRpamQgYmV0ZXIgb20gZGUgZGF0YSB6byBydXcgbW9nZWxpamsgdGUgdG9uZW4hCgpPbWRhdCBlciBuaWV0IHpvdmVlbCBnZWdldmVucyB6aWpuIGt1bm5lbiB3ZSBkZSBkYXRhIHRvZXZvZWdlbiBhYW4gZGUgcGxvdCB6b25kZXIgZGF0IGRpZSB0ZSBkcnVrIHdvcmR0LgoKLSBNZXJrIG9wIGRhdCB3ZSBoZXQgYXJndW1lbnQgYG91dGxpZXIuc2hhcGVgIG9wIE5BIChub3QgYXZhaWxhYmxlKSB6ZXR0ZW4gYG91dGxpZXIuc2hhcGU9TkFgIGluIHRoZSBgZ2VvbV9ib3hwbG90YCBmdW5jdGllIG9tZGF0IHdlIGFuZGVycyBvdXRsaWVycyB0d2VlIGtlZXIgd2VlciB6dWxsZW4gZ2V2ZW4uIEVlcnN0IHZpYSBkZSBib3hwbG90IGxhYWcgZW4gZGFhcm5hIG9tZGF0IHdlIGVlbiBsYWFnIG1ldCBhbGxlIHJ1d2UgZGF0YSB0b2V2b2VnZW4gYWFuIGRlIHBsb3QuCi0gV2UgZ2V2ZW4gZGUgcnV3ZSBkYXRhIHdlZXIgdmlhIGRlICBgZ2VvbV9wb2ludChwb3NpdGlvbj0iaml0dGVyIilgIGZ1bmN0aWUuIFdlIGdlYnJ1aWtlbiBoaWVyYmlqIGhldCBhcmd1bWVudCBwb3NpdGlvbj0naml0dGVyJyB6b2RhdCB3ZSB3YXQgcmFuZG9tIHJ1aXMgdG9ldm9lZ2VuIGFhbiBkZSB4LWNvcmRpbmFhdCB6b2RhdCBkZSBnZWdldmVucyBlbGthYXIgbmlldCBvdmVybGFwcGVuLgoKYGBge3J9CmFwICU+JSAgCiAgZ2dwbG90KGFlcyh4PXRydCx5PXJlbCkpICsKICBnZW9tX2JveHBsb3Qob3V0bGllci5zaGFwZT1OQSkgKwogIGdlb21fcG9pbnQocG9zaXRpb249ImppdHRlciIpCmBgYAoKRGl0IGlzIGVlbiBpbmZvcm1hdGlldmUgcGxvdCEKCi0tLQoKQWFuZ2V6aWVuIHdlIGRlIHBsb3Qgb29rIGhlYmJlbiBvcGdlc2xhZ2VuIGtvbmRlbiB3ZSBkaXQgb29rIGRvZW4gZG9vciBkZSBwbG90IG9wIHRlIHJvZXBlbiBlbiBub2cgZWVuIGxhYWcgdG9lIHRlIHZvZWdlbi4KCmBgYHtyfQphcEJveHBsb3QgKwogIGdlb21fcG9pbnQocG9zaXRpb249ImppdHRlciIpCmBgYAoKV2UgaGFkZGVuIGhldCByZXN1bHRhYXQgb29rIG9wbmlldXcgb3Aga3VubmVuIHNsYWFuIHZvb3IgbGF0ZXIgaGVyZ2VicnVpay4KCmBgYHtyfQphcEJveHBsb3QgPC0gYXBCb3hwbG90ICsKICBnZW9tX3BvaW50KHBvc2l0aW9uPSJqaXR0ZXIiKQpgYGAKCi0tLQoKLSBXZSB6YWdlbiBkdWlkZWxpamsgZWVuIGVmZmVjdCB2YW4gZGUgdHJhbnNwbGFudGF0aWUgb3AgZGUgcmVsYXRpZXZlIGFidW5kYW50aWUgdmFuIFN0YXBoeWxvY29jY3VzLgoKLSBJcyBkYXQgZWZmZWN0IG51IGdyb290IGdlbm9lZyBvbSB0ZSBrdW5uZW4gY29uY2x1ZGVyZW4gZGF0IGRlIGJlaGFuZGVsaW5nIHdlcmt0PwoKLS0tCgpgYGB7ciBvdXQud2lkdGg9JzgwJScsZmlnLmFzcD0uOCwgZmlnLmFsaWduPSdjZW50ZXInLGVjaG89RkFMU0V9CmlmICgicGkiJWluJWxzKCkpIHJtKCJwaSIpCmtvcHZvZXRlcjwtZnVuY3Rpb24oeCx5LGFuZ2xlPTAsbD0uMixjZXguZG90PS41LHBjaD0xOSxjb2w9ImJsYWNrIikKewphbmdsZT1hbmdsZS8xODAqcGkKcG9pbnRzKHgseSxjZXg9Y2V4LmRvdCxwY2g9cGNoLGNvbD1jb2wpCmxpbmVzKGMoeCx4K2wqY29zKC1waS8yK2FuZ2xlKSksYyh5LHkrbCpzaW4oLXBpLzIrYW5nbGUpKSxjb2w9Y29sKQpsaW5lcyhjKHgrbC8yKmNvcygtcGkvMithbmdsZSkseCtsLzIqY29zKC1waS8yK2FuZ2xlKStsLzQqY29zKGFuZ2xlKSksYyh5K2wvMipzaW4oLXBpLzIrYW5nbGUpLHkrbC8yKnNpbigtcGkvMithbmdsZSkrbC80KnNpbihhbmdsZSkpLGNvbD1jb2wpCmxpbmVzKGMoeCtsLzIqY29zKC1waS8yK2FuZ2xlKSx4K2wvMipjb3MoLXBpLzIrYW5nbGUpK2wvNCpjb3MocGkrYW5nbGUpKSxjKHkrbC8yKnNpbigtcGkvMithbmdsZSkseStsLzIqc2luKC1waS8yK2FuZ2xlKStsLzQqc2luKHBpK2FuZ2xlKSksY29sPWNvbCkKbGluZXMoYyh4K2wqY29zKC1waS8yK2FuZ2xlKSx4K2wqY29zKC1waS8yK2FuZ2xlKStsLzIqY29zKC1waS8yK3BpLzQrYW5nbGUpKSxjKHkrbCpzaW4oLXBpLzIrYW5nbGUpLHkrbCpzaW4oLXBpLzIrYW5nbGUpK2wvMipzaW4oLXBpLzIrcGkvNCthbmdsZSkpLGNvbD1jb2wpCmxpbmVzKGMoeCtsKmNvcygtcGkvMithbmdsZSkseCtsKmNvcygtcGkvMithbmdsZSkrbC8yKmNvcygtcGkvMi1waS80K2FuZ2xlKSksYyh5K2wqc2luKC1waS8yK2FuZ2xlKSx5K2wqc2luKC1waS8yK2FuZ2xlKStsLzIqc2luKC1waS8yLXBpLzQrYW5nbGUpKSxjb2w9Y29sKQp9CgpwYXIobWFyPWMoMCwwLDAsMCksbWFpPWMoMCwwLDAsMCkpCnBsb3QoMCwwLHhsYWI9IiIseWxhYj0iIix4bGltPWMoMCwxMCkseWxpbT1jKDAsMTApLGNvbD0wLHhheHQ9Im5vbmUiLHlheHQ9Im5vbmUiLGF4ZXM9RkFMU0UpCnJlY3QoMCw2LDEwLDEwLGJvcmRlcj0icmVkIixsd2Q9MikKdGV4dCguNSw4LCJwb3B1bGF0aW9uIixzcnQ9OTAsY29sPSJyZWQiLGNleD0yKQpzeW1ib2xzICgzLCA4LCBjaXJjbGVzPTEuNSwgY29sPSJyZWQiLGFkZD1UUlVFLGZnPSJyZWQiLGluY2hlcz1GQUxTRSxsd2Q9MikKc2V0LnNlZWQoMzMwKQpncmlkPXNlcSgwLDEuMywuMDEpCgpmb3IgKGkgaW4gMTo1MCkKewoJYW5nbGUxPXJ1bmlmKG49MSxtaW49MCxtYXg9MzYwKQoJYW5nbGUyPXJ1bmlmKG49MSxtaW49MCxtYXg9MzYwKQoJcmFkaXVzPXNhbXBsZShncmlkLHByb2I9Z3JpZF4yKnBpL3N1bShncmlkXjIqcGkpLHNpemU9MSkKCWtvcHZvZXRlcigzK3JhZGl1cypjb3MoYW5nbGUxLzE4MCpwaSksOCtyYWRpdXMqc2luKGFuZ2xlMS8xODAqcGkpLGFuZ2xlPWFuZ2xlMikKfQp0ZXh0KDcuNSw4LCJNaWNyb2Jpb21lIGluIHBvcHVsYXRpb24iLGNvbD0icmVkIixjZXg9MS4yKQoKcmVjdCgwLDAsMTAsNCxib3JkZXI9ImJsdWUiLGx3ZD0yKQp0ZXh0KC41LDIsInNhbXBsZSIsc3J0PTkwLGNvbD0iYmx1ZSIsY2V4PTIpCnN5bWJvbHMgKDMsIDIsIGNpcmNsZXM9MS41LCBjb2w9InJlZCIsYWRkPVRSVUUsZmc9ImJsdWUiLGluY2hlcz1GQUxTRSxsd2Q9MikKZm9yIChpIGluIDA6MSkKCWZvciAoaiBpbiAwOjQpCnsKCglrb3B2b2V0ZXIoMi4xK2oqKDMuOS0yLjEpLzQsMS4xK2kvMixjb2w9InB1cnBsZSIpCn0KZm9yIChpIGluIDI6MykKCWZvciAoaiBpbiAwOjQpCnsKCglrb3B2b2V0ZXIoMi4xK2oqKDMuOS0yLjEpLzQsMS42K2kvMixjb2w9Im9yYW5nZSIpCn0KdGV4dCg3LjUsMiwiTWljcm9iaW9tZSBpbiBzYW1wbGUiLGNvbD0iYmx1ZSIsY2V4PTEuMikKCmFycm93cygzLDUuOSwzLDQuMSxjb2w9ImJsYWNrIixsd2Q9MykKdGV4dCgxLjUsNSwiRVhQLiBERVNJR04gKDEpIixjb2w9ImJsYWNrIixjZXg9MS4yKQp0ZXh0KDcuNSwuNSwiREFUQSBFWFBMT1JBVElPTiAmXG5ERVNDUklQVElWRSBTVEFUSVNUSUNTICgyKSIsY29sPSJibGFjayIsY2V4PTEuMikKYXJyb3dzKDcsNC4xLDcsNS45LGNvbD0iYmxhY2siLGx3ZD0zKQp0ZXh0KDguNSw1LCJFU1RJTUFUSU9OICZcbklORkVSRU5DRSAoMykiLGNvbD0iYmxhY2siLGNleD0xLjIpCmBgYAoKLS0tCgotIEluZHVjdGllOiBEb29yIG1pZGRlbCB2YW4gc3RhdGlzdGlzY2hlIGJlc2x1aXR2b3JtaW5nIChpbmZlcmVuY2UpIGt1bm5lbiB3ZSB1aXRzcHJha2VuIGRvZW4gb3ZlciBkZSBwb3B1bGF0aWUgb3AgYmFzaXMgdmFuIGVlbiBzdGVla3Byb2VmLgoKLSBEZSBwcmlqcyBkaWUgd2UgaGllcnZvb3IgYmV0YWxlbiBpcyBvbnpla2VyaGVpZCEKCi0gV2Uga3VubmVuIG9wIGJhc2lzIHZhbiBlZW4gc3RlZWtwcm9lZiBub29pdCBhYnNvbHV1dCB6ZWtlciB6aWpuIHZhbiBvbnplIGNvbmNsdXNpZXMuCgotLS0KCi0gTWV0IGRhdGEga3VubmVuIHdlIG5pZXQgYmV3aWp6ZW4gZGF0IGVlbiBiZWhhbmRlbGluZyB3ZXJrdC4KCi0gRmFsc2lmaWNhdGllIHByaW5jaXBlIHZhbiBQb3BwZXI6IERhdGEga3VubmVuIGVua2VsIGVlbiBoeXBvdGhlc2Ugb2YgZWVuIHRoZW9yaWUgb250a3JhY2h0ZW4uCgotIE1ldCBzdGF0aXN0aWVrIGt1bm5lbiB3ZSBkdXMgbmlldCBhYW50b25lbiBkYXQgZGUgYmVoYW5kZWxpbmcgd2Vya3QuCgotIFN0YXRpc3RpZWsgemFsIG9ucyB3ZWwgdG9lbGF0ZW4gb20gaGV0IG9tZ2VrZWVyZGUgdGUgZmFsc2lmacOrcmVuOiBhbHMgd2UgdmVyb25kZXJzdGVsbGVuIGRhdCBlciBnZWVuIGVmZmVjdCB2YW4gZGUgYmVoYW5kZWxpbmcsIHNwcmVla3QgZGUgZGF0YSBpbiBkZSBzdGVla3Byb2VmIGRpdCB0ZWdlbj8KCi0gTWV0IHN0YXRpc3RpZWsga3VubmVuIHdlIGJlcmVrZW5lbiBob2Ugd2FhcnNjaGlqbmxpamsgaGV0IGlzIG9tIGluIGVlbiByYW5kb20gc3RlZWtwcm9lZiAod2FubmVlciB3ZSBoZXQgZXhwZXJpbWVudCBkdXMgb3BuaWV1dyB1aXQgem91ZGVuIHZvZXJlbikgZWVuIGdlbWlkZGVsZCB2ZXJzY2hpbCBpbiByZWxhdGlldmUgYWJ1bmRhbnRpZSB0ZSB6aWVuIHR1c3NlbiBwbGFjZWJvIGVuIHRyYW5zcGxhbnRhdGllZ3JvZXAgZGF0IG1pbnN0ZW5zIHpvIGdyb290IGlzIGFscyBpbiBvbnplIHN0ZWVrcHJvZWYgYWxzIGRlIGJlaGFuZGVsaW5nIGdlZW4gZWZmZWN0IHpvdSBoZWJiZW4uCgotIERpZSBrYW5zIHdvcmR0IGVlbiBwLXdhYXJkZSBnZW5vZW1kLgoKLSBBbHMgcCBoZWVsIGtsZWluIGlzLCBkYW4gaXMgaGV0IGhlZWwgb253YWFyc2NoaWpubGlqayBvbSBlZW4gZGVyZ2VsaWprIGVmZmVjdCB0ZSBvYnNlcnZlcmVuIGluIGVlbiBzdGVla3Byb2VmIGRvb3IgdG9ldmFsLgoKLSBwIHdvcmR0IG1lZXN0YWwgdmVyZ2VsZWtlbiBtZXQgNSUuIEFscyBlciBnZWVuIGVmZmVjdCBpcyB2YW4gZGUgYmVoYW5kZWxpbmcgZGFuIHRvbGVyZXJlbiA1JSB2YWxzIHBvc2l0aWV2ZSBjb25jbHVzaWVzLgoKLSBPbSBkZSBrYW5zIHAgdGUgYmVyZWtlbmVuIGlzIGhldCBub2RpZyBvbSBkZSBkYXRhIHRlIG1vZGVsbGVyZW4gbWV0IHN0YXRpc3Rpc2NoZSBtb2RlbGxlbi4KCi0tLQoKSW4gbGF0ZXJlIGhvb2Zkc3R1a2tlbiB6dWxsZW4gd2UgemllbiBkYXQgd2UgdC10ZXN0IGt1bm5lbiBnZWJydWlrZW4gb20gaGV0Z2VlbiB3ZSBvYnNlcnZlcmVuIGluIGRlIG1pY3JvYmlvbWUgZGF0YXNldCB0ZSB2ZXJhbGdlbWVuZW4gbmFhciBkZSBwb3B1bGF0aWUuCgpgYGB7cn0KYXAgJT4lIHQudGVzdChyZWx+dHJ0LGRhdGE9LikKYGBgCgpDb25jbHVzaWU6CkdlbWlkZGVsZCBpcyBkZSByZWxhdGlldmUgYWJ1bmRhbnRpZSB2YW4gU3RhcGh5bG9jb2NjdXMgaW4gaGV0IG1pY3JvYmlvbWUgdmFuIHBlcnNvbmVuIG1ldCBlZW4gendlZXRnZXVyIGByIGZvcm1hdChhcFJlbFN1bSRtZWFuWzJdLWFwUmVsU3VtJG1lYW5bMV0sZGlnaXRzPTMpYCUgaG9nZXIgbmEgZGUgdHJhbnNwbGFudGllIGRhbiBuYSBkZSBwbGFjZWJvIGJlaGFuZGVsaW5nLgoKLS0tCgojIyBSYW5kb21pc2F0aWUKCi0gV2F0IHdvcmR0IHppam4gZGUgY29uc2VxdWVudGllcyB2YW4gaGV0IGdlYnJ1aWsgdmFuIGVlbiBzdGVla3Byb2VmIGVuIHZhbiByYW5kb21pc2F0aWU/CgotIFJhbmRvbWlzYXRpZSBpcyBzdGVyayBnZXJlbGF0ZWVyZCBtZXQgaGV0IGNvbmNlcHQgdmFuIGRlIHBvcHVsYXRpZSBlbiBzY29wZSB2YW4gZGUgc3R1ZGllLiAgCgotIERlIHNjb3BlIHZhbiBkZSBzdHVkaWUgbW9ldCBnb2VkIHdvcmRlbiBvbXNjaHJldmVuIHZvb3IgZGUgc3RhcnQgdmFuIGhldCBleHBlcmltZW50LgoKLSBPbWRhdCBkZSBzdGF0aXN0aXNjaGUgYW5hbHlzZSB2YWxpZGUgem91IHppam4gaXMgaGV0IG5vb2R6YWtlbGlqayBkYXQgZGUgc3ViamVjdGVuIHZvbGxlZGlnIHJhbmRvbSB3b3JkZW4gZ2V0cm9ra2VuIHVpdCBkZSBwb3B1bGF0aWUgbmFhciB3YWFyIHdlIG9uemUgY29uY2x1c2llcyB3ZW5zZW4gdGUgdmVyYWxnZW1lbmVuLgoKLSBWb2xsZWRpZyByYW5kb20gdHJla2tlbiB2YW4gZGUgcG9wdWxhdGllIGltcGxpY2VlcnQgZGF0OgoKICAgIC0gYWxsZSBzdWJqZWN0ZW4gdmFuIGRlIHBvcHVsYXRpZSBldmVudmVlbCBrYW5zIGhlYmJlbiBvbSBpbiBkZSBzdGVla3Byb2VmIHRlIHdvcmRlbiBvcGdlbm9tZW4KICAgIC0gZGUgc2VsZWN0aWUgdmFuIGVlbiBzdWJqZWN0IG9uYWZoYW5rZWxpamsgaXMgdmFuIGRlIGFuZGVyZSBzdWJqZWN0ZW4gaW4gZGUgc3RlZWtwcm9lZi4KCgotIERlIHN0ZWVrcHJvZWYgaXMgZGFuIHJlcHJlc2VudGF0aWVmIHZvb3IgZGUgcG9wdWxhdGllLCBtYWFyIGlzIG5vZyBzdGVlZHMgcmFuZG9tLgoKLSBXYXQgYmV0ZWtlbnQgZGl0PwoKLS0tCgojIENhc2Ugc3R1ZHk6IExlbmd0ZSB2YW4gbWFubmVuIGVuIHZyb3V3ZW4gXC0gVmFyaWFiaWxpdGVpdCB2YW4gc3RlZWtwcm9lZiB0b3Qgc3RlZWtwcm9lZgoKLSBPbSB0ZSBiZWdyaWpwZW4gZGF0IGVlbiBzdGVla3Byb2VmIHJhbmRvbSBpcyB6b3VkZW4gd2UgaGV0emVsZmRlIGV4cGVyaW1lbnQgdmVlbCBrZWVyIG1vZXRlbiBrdW5uZW4gaGVyaGFsZW4gKGByZXBlYXRlZCBzYW1wbGluZ2ApLgoKLSBEYW4gem91ZGVuIHdlIGluemljaHQga3VubmVuIGtyaWpnZW4gaG9lIGRlIGdlZ2V2ZW5zIHZlcmFuZGVyZW4gdmFuIHN0ZWVrcHJvZWYgdG90IHN0ZWVrcHJvZWYuCgotIE9tIGRpdCB0ZSBpbGx1c3RyZXJlbiB6dWxsZW4gd2UgZ2VicnVpayBtYWtlbiB2YW4gZWVuIGhlbGUgZ3JvdGUgc3R1ZGllLgoKLSBVaXQgZGllIHN0dWRpZSB6dWxsZW4gd2UgZGFuIGhlcmhhYWxkZWxpamsga2xlaW5lIHN0ZWVrcHJvZXZlbiB0cmVra2VuIG9tIHRlIGJlZ3JpanBlbiBob2UgZGUgZ2VnZXZlbnMgZW4gc3RhdGlzdGlla2VuIHZlcmFuZGVyZW4gdmFuIHN0ZWVrcHJvZWYgdG90IHN0ZWVrcHJvZWYuIE9mIG9tIG1ldCBhbmRlcmUgd29vcmRlbiBuYSB0ZSBnYWFuIHdhdCBkZSB2YXJpYWJpbGl0ZWl0IGlzIHR1c3NlbiBzdGVla3Byb2V2ZW4uCgotLS0KCk5hdGlvbmFsIEhlYWx0aCBBbmQgTnV0cml0aW9uIEV4YW1pbmF0aW9uIFN0dWR5IChOSEFORVMpCgogIC0gU2luZHMgMTk2MCB3b3JkZW4gZWxrIGphYXIgbWVuc2VuIHZhbiBhbGxlIGxlZWZ0aWpkZW4gZ2XDr250ZXJ2aWV3ZCBiaWogaGVuIHRodWlzLgogIC0gRXIgbWFha3Qgb29rIGVlbiBnZXpvbmRoZWlkc29uZGVyem9layBkZWVsIHVpdCB2YW4gZGUgc3R1ZHkgZGllIGluIGVlbiBtb2JpZWwgb25kZXJ6b2Vrc2NlbnRydW0gd29yZHQgYWZnZW5vbWVuLgogIC0gV2UgenVsbGVuIGRlemUgZ3JvdGUgc3R1ZGllIGdlYnJ1aWtlbiBvbSBhdCByYW5kb20gcGVyc29uZW4gdGUgc2VsZWN0ZXJlbiB2YW4gZGUgQW1lcmlrYWFuc2UgcG9wdWxhdGllLgogIC0gRGF0IHphbCBpbnppY2h0IGdldmVuIGluIGhvZSBkZSBnZWdldmVucyBlbiByZXN1bHRhdGVuIHZhbiBlZW4gYW5hbHlzZSB6dWxsZW4gdmFyacOrcmVuIHZhbiBzdGVla3Byb2VmIHRvdCBzdGVla3Byb2VmLgogIC0gRGUgZGF0YSB2YW4gZGV6ZSBzdHVkaWUgaXMgdGVydWcgdGUgdmluZGVuIGluIGhldCBSIHBha2tldCBgTkhBTkVTYAoKLS0tCgpgYGB7cn0KbGlicmFyeShOSEFORVMpCmhlYWQoTkhBTkVTKQpnbGltcHNlKE5IQU5FUykKYGBgCgotLS0KCiMjIERhdGEgZXhwbG9yYXRpZQoKCgpPbmRlcnpvZWtzdnJhYWc6IGhvZSB2ZXJzY2hpbHQgZGUgbGVuZ3RlIHZhbiB2b2x3YXNzZW4gbWFubmVuIGVuIHZyb3V3ZW4uCgoxLiBXZSBwaXBlbiBkZSBkYXRhc2V0IG5hYXIgZGUgZnVuY3Rpb24gYGZpbHRlcmAgb20gZGUgZGF0YSB0ZSBmaWx0ZXJlbiB2b2xnZW5zIGxlZWZ0aWpkLiAgCjIuIFdlIHBsb3R0ZW4gZGUgbGVuZ3RlIG1ldGluZ2VuLgogICAgLSBXZSBzZWxlY3RlcmVuIGRlIGRhdGEgZGF0YSBtZXQgaGV0IGNvbW1hbmRvIGBnZ3Bsb3QoYWVzKHg9bGVuZ3RlKSlgCiAgICAtIFdlIHZvZWdlbiBlZW4gaGlzdG9ncmFtIHRvZSBtZXQgaGV0IGNvbW1hbmRvIGBnZW9tX2hpc3RvZ3JhbSgpYAogICAgLSBXZSBtYWtlbiB0d2VlIHZlcnRpa2FsZSBwYW5lbHMgbWV0IGhldCBjb21tYW5kbyBgZmFjZXRfZ3JpZChHZW5kZXJ+LilgCiAgICAtIFdlIHZlcmFuZGVyZW4gaGV0IGxhYmVsIHZhbiBkZSB4LWFzIG1ldCBkZSBgeGxhYmAgZnVuY3RpZS4KCmBgYHtyfQpOSEFORVMlPiUgIAogIGZpbHRlcihBZ2UgPiAxOCAmICFpcy5uYShIZWlnaHQpKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBIZWlnaHQpKSsKICBnZW9tX2hpc3RvZ3JhbSgpICsKICBmYWNldF9ncmlkKEdlbmRlciB+IC4pICsKICB4bGFiKCJMZW5ndGUgKGNtKSIpCmBgYAoKLS0tCgpXZSB6aWVuIGRhdCBkZSBkYXRhIG51IG1pbiBvZiBtZWVyIHN5bW1ldHJpc2NoIHZlcmRlZWxkIHppam4gZW4gZWVuIGtsb2t2b3JtIGhlYmJlbi4gIApEYXQgemFsIG9ucyB0b2UgbGF0ZW4gb20gZGUgZGF0YSB2ZXJkZXIgc2FtZW4gdGUgdmF0dGVuIGRvb3IgZ2VicnVpayB0ZSBtYWtlbiB2YW4gdHdlZSBzdGF0aXN0aWVrZW46IGhldCBnZW1pZGRlbGRlIGVuIGRlIHN0YW5kYWFyZCBkZXZpYXRpZSB3YXQgZWVuIG1hYXQgaXMgdm9vciBkZSBzcHJlaWRpbmcgdmFuIGRlIGdlZ2V2ZW5zIHJvbmQgaGV0IGdlbWlkZGVsZGUuCgotLS0KCldlIG1ha2VuIG51IGVlbiBzdWJzZXQgdmFuIGRlIGRhdGEgZGllIHdlIHp1bGxlbiBnZWJydWlrZW4gb20gYWFuIHRlIHRvbmVuIGhvZSBkZSB2YXJpYWJpbGl0ZWl0IGluIGtsZWluZSBzdGVla3Byb2V2ZW4ga2FuIHZhcmnDq3JlbiB2YW4gc3RlZWtwcm9lZiB0b3Qgc3RlZWtwcm9lZi4KCiAgMS4gV2UgZmlsdGVyZW4gb3AgbGVlZnRpamQgZW4gdmVyd2lqZGVyZW4gb250YnJla2VuZGVuIGdlZ2V2ZW5zIChOQSwgTm90IEF2YWlsYWJsZSkuCiAgMi4gV2Ugc2VsZWN0ZXJlbiBlbmtlbCBoZXQgZ2VzbGFjaHQgZW4gTGVuZ3RlIHpvZGF0IGRlIGRhdGFzZXQgZ2VlbiBvbm5vZGlnZSB2YXJpYWJlbGVuIGJldmF0LgoKYGBge3J9Cm5oYW5lc1N1YiA8LSBOSEFORVMgJT4lCiAgZmlsdGVyKEFnZSA+IDI1ICYgIWlzLm5hKEhlaWdodCkpICU+JQogIHNlbGVjdChjKCJHZW5kZXIiLCJIZWlnaHQiKSkKYGBgCgotLS0KCldlIGJlcmVrZW5lbiBoZXQgZ2VtaWRkZWxkZSBlbiBkZSBzdGFuZGFhcmQgZGV2aWF0aWUgdm9vciBkZSBsZW5ndGUgdm9vciBtYW5uZW4gZW4gdnJvdXdlbiBpbiBkZSBncm90ZSBkYXRhc2V0LgpXZSBncm9lcGVyZW4gZGUgZGF0YSBoaWVydm9vciBvcCBiYXNpcyB2YW4gaGV0IGdlc2xhY2h0ICh2YXJpYWJsZSBHZW5kZXIpLgoKCmBgYHtyfQoKSGVpZ2h0U3VtIDwtIG5oYW5lc1N1YiAlPiUKICBncm91cF9ieShHZW5kZXIpICU+JQogIHN1bW1hcml6ZV9hdCgiSGVpZ2h0IiwKICAgICAgICAgICAgICAgbGlzdChtZWFuID0gbWVhbiwKICAgICAgICAgICAgICAgc2QgPSBzZCkKICAgICAgICAgICAgICApCgprbml0cjo6a2FibGUoCiAgSGVpZ2h0U3VtICU+JQogIG11dGF0ZV9pZihpcy5udW1lcmljLCByb3VuZCwgZGlnaXRzPTEpCiAgKQpgYGAKCi0tLQoKIyMgRXhwZXJpbWVudAoKLSBTdGVsIGRhdCB3ZSBnZWVuIHRvZWdhbmcgaGViYmVuIHRvdCBkZSBtZXRpbmdlbiB2YW4gZGUgTkhBTkVTIHN0dWRpZS4KCi0gV2Ugem91ZGVuIGRhbiBlZW4gZXhwZXJpbWVudCBvcCBtb2V0ZW4gemV0dGVuIG9tIG1ldGluZ2VuIGJpaiBtYW5uZW4gZW4gdnJvdXdlbiB0ZSBkb2VuLgoKLSBWZXJvbmRlcnN0ZWwgZGF0IHdlIGJ1ZGdldCBoZWJiZW4gb20gbWV0aW5nZW4gYmlqIDUgbWFubmVuIGVuIDUgdnJvdXdlbiB0ZSBkb2VuLgoKLSBXZSB6b3VkZW4gZGFuIDUgbWFubmVuIGVuIDUgdnJvdXdlbiBib3ZlbiBkZSAyNSBqYWFyIGF0IHJhbmRvbSBzZWxlY3RlcmVuIHVpdCBkZSBBbWVyaWthYW5zZSBwb3B1bGF0aWUuCgotIFdlIGt1bm5lbiBkaXQgZXhwZXJpbWVudCBzaW11bGVyZW4gZG9vciA1IHZyb3V3ZW4gZW4gNSBtYW5uZW4gYXQgcmFuZG9tIHRlIHNlbGVjdGVyZW4gdWl0IGRlIE5IQU5FUyBzdHVkaWUuCgotLS0KCmBgYHtyfQpzZXQuc2VlZCgxMDAwMDAxKQpuU2FtcCA8LSA1CmZlbSA8LSBuaGFuZXNTdWIgJT4lCiAgZmlsdGVyKEdlbmRlcj09ImZlbWFsZSIpICU+JQogIHNhbXBsZV9uKHNpemU9NSkKCm1hbCA8LSBuaGFuZXNTdWIgJT4lCiAgZmlsdGVyKEdlbmRlcj09Im1hbGUiKSAlPiUKICBzYW1wbGVfbihzaXplPTUpCgpzYW1wMSA8LSByYmluZChmZW0sbWFsKQoKc2FtcDEKYGBgCgotLS0KCkRhdGEgRXhwbG9yYXRpZQoKYGBge3J9CnNhbXAxICU+JQogIGdncGxvdChhZXMoeD1IZWlnaHQpKSArCiAgZ2VvbV9oaXN0b2dyYW0oKSArCiAgZmFjZXRfZ3JpZChHZW5kZXJ+LikgKwogIHhsYWIoIkxlbmd0ZSAoY20pIikKCkhlaWdodFN1bUV4cDEgPC0gc2FtcDEgJT4lCiAgZ3JvdXBfYnkoR2VuZGVyKSAlPiUKICBzdW1tYXJpemVfYXQoIkhlaWdodCIsCiAgICAgICAgICAgICAgIGxpc3QobWVhbiA9IG1lYW4sCiAgICAgICAgICAgICAgICAgICAgICBzZCA9IHNkKQogICAgICAgICAgICAgICAgICApCkhlaWdodFN1bUV4cDEKYGBgCgpIaXN0b2dyYW0gaXMgbmlldCB6aW52b2wgYWxzIHdlIG1hYXIgem8gd2VpbmlnIGRhdGFwdW50ZW4gaGViYmVuLgoKLS0tCgoKQm94cGxvdCBpcyBiZXRlcjoKCmBgYHtyIGVjaG89RkFMU0V9CnNhbXAxICU+JQogIGdncGxvdChhZXMoeCA9IEdlbmRlcix5ID0gSGVpZ2h0KSkgKwogIGdlb21fYm94cGxvdChvdXRsaWVyLnNoYXBlID0gTkEpICsKICBnZW9tX3BvaW50KHBvc2l0aW9uID0gImppdHRlciIpICsKICBnZW9tX3BvaW50KAogICAgYWVzKHggPSAxLCB5ID0gSGVpZ2h0U3VtRXhwMSRtZWFuWzFdKSwKICAgIHNpemUgPSAzLAogICAgcGNoID0gMTcsCiAgICBjb2xvcj0iZGFya3JlZCIpICsKICBnZW9tX3BvaW50KAogICAgYWVzKHggPSAyLCB5ID0gSGVpZ2h0U3VtRXhwMSRtZWFuWzFdKSwKICAgIHNpemUgPSAzLAogICAgcGNoID0gMTcsCiAgICBjb2xvciA9ICJkYXJrcmVkIikgKwogIHlsYWIoIkhlaWdodCAoY20pIikKYGBgCgotLS0KCldlIHZvZXJlbiBoaWVyIG9vayBlZW4gdC10ZXN0IHVpdC4KCmBgYHtyfQp0LnRlc3QoSGVpZ2h0fkdlbmRlcixkYXRhPXNhbXAxKQpgYGAKCkluIGhldCBleHBlcmltZW50IHppam4gdnJvdXdlbiB6aWpuIGdlbWlkZGVsZCBgciByb3VuZChhYnMoSGVpZ2h0U3VtRXhwMSRtZWFuWzFdLUhlaWdodFN1bUV4cDEkbWVhblsyXSksMilgIGNtIGByIGlmZWxzZShIZWlnaHRTdW1FeHAxJG1lYW5bMV0+SGVpZ2h0U3VtRXhwMSRtZWFuWzJdLCJncm90ZXIiLCJrbGVpbmVyIilgIGRhbiBtYW5uZW4uIEVuIGFscyB3ZSBlZW4gc3RhdGlzdGlzY2hlIHRlc3QgdWl0dm9lcmVuICh6aWUgaG9vZmRzdHVrIDU6IFN0YXRpc3Rpc2NoZSBiZXNsdWl0dm9ybWluZykga3VubmVuIHdlIGJlc2x1aXRlbiBkYXQgZGl0IHZlcnNjaGlsIHN0YXRpc3Rpc2NoIGByIGlmZWxzZSh0LnRlc3QoSGVpZ2h0fkdlbmRlcixzYW1wMSkkcC52YWx1ZSA8IDAuMDUsInNpZ25pZmljYW50IiwibmlldCBzaWduaWZpY2FudCIpYCBpcy4KCi0tLQoKIyMgSGVyaGFhbCBoZXQgZXhwZXJpbWVudAoKQWxzIHdlIGhldCBleHBlcmltZW50IGhlcmhhbGVuIHNlbGVjdGVyZW4gd2UgYW5kZXJlIG1lbnNlbiBlbiB2ZXJrcmlqZ2VuIHdlIGFuZGVyZSByZXN1bHRhdGVuLgoKCmBgYHtyfQpmZW0gPC0gbmhhbmVzU3ViICU+JQogIGZpbHRlcihHZW5kZXI9PSJmZW1hbGUiKSAlPiUKICBzYW1wbGVfbihzaXplPTUpCgptYWwgPC0gbmhhbmVzU3ViICU+JQogIGZpbHRlcihHZW5kZXI9PSJtYWxlIikgJT4lCiAgc2FtcGxlX24oc2l6ZT01KQoKc2FtcDIgPC0gcmJpbmQoZmVtLG1hbCkKCkhlaWdodFN1bUV4cDIgPC0gc2FtcDIgJT4lCiAgZ3JvdXBfYnkoR2VuZGVyKSAlPiUKICBzdW1tYXJpemVfYXQoIkhlaWdodCIsCiAgICAgICAgICAgICAgIGxpc3QobWVhbj1tZWFuLAogICAgICAgICAgICAgICAgICAgIHNkPXNkKQogICAgICAgICAgICAgICkKSGVpZ2h0U3VtRXhwMgoKc2FtcDIgJT4lCiAgZ2dwbG90KGFlcyh4ID0gR2VuZGVyLHkgPSBIZWlnaHQpKSArCiAgZ2VvbV9ib3hwbG90KG91dGxpZXIuc2hhcGUgPSBOQSkgKwogIGdlb21fcG9pbnQocG9zaXRpb24gPSAiaml0dGVyIikgKwogIGdlb21fcG9pbnQoCiAgICBhZXMoeCA9IDEsIHkgPSBIZWlnaHRTdW1FeHAxJG1lYW5bMV0pLAogICAgc2l6ZSA9IDMsCiAgICBwY2ggPSAxNywKICAgIGNvbG9yPSJkYXJrcmVkIikgKwogIGdlb21fcG9pbnQoCiAgICBhZXMoeCA9IDIsIHkgPSBIZWlnaHRTdW1FeHAxJG1lYW5bMV0pLAogICAgc2l6ZSA9IDMsCiAgICBwY2ggPSAxNywKICAgIGNvbG9yID0gImRhcmtyZWQiKSArCiAgeWxhYigiSGVpZ2h0IChjbSkiKQoKdC50ZXN0KEhlaWdodCB+IEdlbmRlciwgZGF0YT1zYW1wMikKYGBgCgoKSW4gZGUgbmlldXdlIHN0ZWVrcHJvZWYgemlqbiB2cm91d2VuIHppam4gZ2VtaWRkZWxkIGByIHJvdW5kKGFicyhIZWlnaHRTdW1FeHAyJG1lYW5bMV0tSGVpZ2h0U3VtRXhwMiRtZWFuWzJdKSwyKWAgY20gYHIgaWZlbHNlKEhlaWdodFN1bUV4cDIkbWVhblsxXT5IZWlnaHRTdW1FeHAyJG1lYW5bMl0sImdyb3RlciIsImtsZWluZXIiKWAgZGFuIG1hbm5lbi4gRW4gZGl0IHZlcnNjaGlsIGlzIHN0YXRpc3Rpc2NoIGByIGlmZWxzZSh0LnRlc3QoSGVpZ2h0fkdlbmRlcixzYW1wMix2YXIuZXF1YWw9VFJVRSkkcC52YWx1ZSA8IDAuMDUsInNpZ25pZmljYW50IiwibmlldCBzaWduaWZpY2FudCIpYAoKCi0tLQoKIyMgSGVyaGFhbCBoZXQgZXhwZXJpbWVudCBvcG5pZXV3CgpgYGB7cn0Kc2VlZCA8LSAxMzM2NjAyCmZlbSA8LSBuaGFuZXNTdWIgJT4lCiAgZmlsdGVyKEdlbmRlcj09ImZlbWFsZSIpICU+JQogIHNhbXBsZV9uKHNpemU9NSkKCm1hbCA8LSBuaGFuZXNTdWIgJT4lCiAgZmlsdGVyKEdlbmRlcj09Im1hbGUiKSAlPiUKICBzYW1wbGVfbihzaXplPTUpCgpzYW1wMyA8LSByYmluZChmZW0sbWFsKQoKSGVpZ2h0U3VtRXhwMyA8LSBzYW1wMyAlPiUKICBncm91cF9ieShHZW5kZXIpICU+JQogIHN1bW1hcml6ZV9hdCgiSGVpZ2h0IiwKICAgICAgICAgICAgICAgbGlzdChtZWFuPW1lYW4sCiAgICAgICAgICAgICAgICAgICAgc2Q9c2QpCiAgICAgICAgICAgICAgKQpIZWlnaHRTdW1FeHAzCgpzYW1wMyAlPiUKICBnZ3Bsb3QoYWVzKHggPSBHZW5kZXIseSA9IEhlaWdodCkpICsKICBnZW9tX2JveHBsb3Qob3V0bGllci5zaGFwZSA9IE5BKSArCiAgZ2VvbV9wb2ludChwb3NpdGlvbiA9ICJqaXR0ZXIiKSArCiAgZ2VvbV9wb2ludCgKICAgIGFlcyh4ID0gMSwgeSA9IEhlaWdodFN1bUV4cDEkbWVhblsxXSksCiAgICBzaXplID0gMywKICAgIHBjaCA9IDE3LAogICAgY29sb3I9ImRhcmtyZWQiKSArCiAgZ2VvbV9wb2ludCgKICAgIGFlcyh4ID0gMiwgeSA9IEhlaWdodFN1bUV4cDEkbWVhblsxXSksCiAgICBzaXplID0gMywKICAgIHBjaCA9IDE3LAogICAgY29sb3IgPSAiZGFya3JlZCIpICsKICB5bGFiKCJIZWlnaHQgKGNtKSIpCgp0LnRlc3QoSGVpZ2h0IH4gR2VuZGVyLCBkYXRhPXNhbXAzKQpgYGAKCkluIGRlIG5pZXV3ZSBzdGVla3Byb2VmIHppam4gdnJvdXdlbiBnZW1pZGRlbGQgYHIgcm91bmQoYWJzKEhlaWdodFN1bUV4cDMkbWVhblsxXS1IZWlnaHRTdW1FeHAzJG1lYW5bMl0pLDIpYCBjbSBgciBpZmVsc2UoSGVpZ2h0U3VtRXhwMyRtZWFuWzFdPkhlaWdodFN1bUV4cDMkbWVhblsyXSwiZ3JvdGVyIiwia2xlaW5lciIpYCBkYW4gbWFubmVuLiBFbiBkaXQgdmVyc2NoaWwgaXMgc3RhdGlzdGlzY2ggYHIgaWZlbHNlKHQudGVzdChIZWlnaHR+R2VuZGVyLHNhbXAzLHZhci5lcXVhbD1UUlVFKSRwLnZhbHVlIDwgMC4wNSwic2lnbmlmaWNhbnQiLCJuaWV0IHNpZ25pZmljYW50IilgCgotLS0KCiMjIFNhbWVudmF0dGluZwoKLSBXZSB0cm9ra2VuIGF0IHJhbmRvbSBhbmRlcmUgcHJvZWZwZXJzb25lbiBpbiBlbGtlIHN0ZWVrcHJvZWYKCi0gSGllcmRvb3IgdmVyc2NoaWxsZW4gbGVuZ3RlbWV0aW5nZW4gdmFuIHN0ZWVrcHJvZWYgdG90IHN0ZWVrcHJvZWYuCgotIER1cyBvb2sgZGUgZ2VzY2hhdHRlIGdlbWlkZGVsZGVzIGVuIHN0YW5kYWFyZCBkZXZpYXRpZXMuCgotIEJpamdldm9sZyB6aWpuIG9uemUgY29uY2x1c2llcyBvb2sgb256ZWtlciBlbiBrdW5uZW4gZGV6ZSB3aWp6aWdlbiB2YW4gc3RlZWtwcm9lZiB0b3Qgc3RlZWtwcm9lZi4KCi0gU3RlZWtwcm9ldmVuIHdhYXJiaWogaGV0IGVmZmVjdCB0ZWdlbmdlc3RlbGQgaXMgYWFuIGRhdCBpbiBkZSBwb3B1bGF0aWUgZW4gd2FhcmJpaiB3ZSBiZXNsdWl0ZW4gZGF0IGhldCB2ZXJzY2hpbCBzaWduaWZpY2FudCBpcywgemlqbiB6ZWxkemFhbS4KCiRccmlnaHRhcnJvdyQgTWV0IHN0YXRpc3RpZWsgY29udHJvbGVyZW4gd2UgZGUga2FucyBvcCBoZXQgdHJla2tlbiBmb3V0ZSBjb25jbHVzaWVzLgoKLSBEaXQgd29yZHQgaW4gZGUgb25kZXJzdGFhbmRlIGNvZGUgZ2XDr2xsdXN0cmVlcmQuIFdlIHRyZWtrZW4gMTAwMDAgaGVyaGFhbGRlIHN0ZWVrcHJvZXZlbiB2YW4gNSB2cm91d2VuIGVuIDUgbWFubmVuIHVpdCBkZSBOSEFORVMgc3R1ZGllLgoKYGBge3J9CiMgQWFudGFsIHNpbXVsYXRpZXMgZW4gc3RlZWtwcm9lZmdyb290dGUgcGVyIGdyb2VwCm5TaW0gPC0gMTAwMDAKblNhbXAgPC0gNQoKIyBXZSBmaWx0ZXJlbiBkZSBkYXRhIHZvb3JhZiB6b2RhdCB3ZSBkaXQgbmlldCB0ZWxrZW5zIG9wbmlldXcgaG9ldmVuIHRlIGRvZW4KZmVtIDwtIG5oYW5lc1N1YiAlPiUKICBmaWx0ZXIoR2VuZGVyID09ICJmZW1hbGUiKQoKbWFsIDwtIG5oYW5lc1N1YiAlPiUKICBmaWx0ZXIoR2VuZGVyID09ICJtYWxlIikKCiMgU2ltdWxhdGllIHN0dWRpZQojIE9tIHNuZWxsZSBmdW5jdGllcyB0ZSBrdW5uZW4gZ2VicnVpa2VuIG5lbWVuIHdlIGVlcnN0IG5TaW0gc3RlZWtwcm9ldmVuIGVuIGJlcmVrZW5lbiB3ZSBkYWFybmEgYWxsZXMuCgpmZW1TYW1wcyA8LSBtYWxTYW1wcyA8LW1hdHJpeChOQSwgbnJvdz1uU2FtcCwgbmNvbD1uU2ltKQpmb3IgKGkgaW4gMTpuU2ltKQp7CiAgZmVtU2FtcHNbLGldIDwtIHNhbXBsZShmZW0kSGVpZ2h0LCBuU2FtcCkKICBtYWxTYW1wc1ssaV0gPC0gc2FtcGxlKG1hbCRIZWlnaHQsIG5TYW1wKQp9CgpyZXMgPC0gZGF0YS5mcmFtZSgKICB2ZXJzY2hpbD1jb2xNZWFucyhmZW1TYW1wcykgLSBjb2xNZWFucyhtYWxTYW1wcyksCiAgUmZhc3Q6OnR0ZXN0cyhmZW1TYW1wcywgbWFsU2FtcHMpCiAgKQoKc3VtKHJlcyRwdmFsdWUgPCAwLjA1ICYgcmVzJHZlcnNjaGlsIDwgMCkKc3VtKHJlcyRwdmFsdWUgPj0gMC4wNSkKc3VtKHJlcyRwdmFsdWUgPCAwLjA1ICYgcmVzJHZlcnNjaGlsPjApCgpyZXMgJT4lCiAgZ2dwbG90KGFlcyh4PXZlcnNjaGlsLHk9LWxvZzEwKHB2YWx1ZSksY29sb3I9cHZhbHVlIDwgMC4wNSkpICsKICBnZW9tX3BvaW50KCkgKwogIHhsYWIoIkdlbWlkZGVsZCBWZXJzY2hpbCAoY20pIikgKwogIHlsYWIoIlN0YXRpc3Rpc2NoZSBTaWduaWZpY2FudGllICgtbG9nMTAgcCkiKQoKcmVzICU+JQogIGdncGxvdChhZXMoeSA9IHZlcnNjaGlsKSkgKwogIGdlb21fYm94cGxvdCgpICsKICB5bGFiKCJHZW1pZGRlbGQgVmVyc2NoaWwgKGNtKSIpCiAgeGxhYigiIikKYGBgCgpPcCBiYXNpcyB2YW4gMTAgMDAwIHN0ZWVrcHJvZXZlbiB2YW4gNSBtYW5uZW4gZW4gNSB2cm91d2VuIHphZ2VuIHdlIGRhdCBpbiBgciBzdW0ocmVzJHB2YWx1ZTwwLjA1JnJlcyR2ZXJzY2hpbDwwKWAgc3RlZWtwcm9ldmVuIHZyb3V3ZW4gZ2VtaWRkZWxkIHNpZ25pZmljYW50IGtsZWluZXIgemlqbiBkYW4gbWFubmVuLiBJbiBgciBzdW0ocmVzJHB2YWx1ZT49MC4wNSlgIHN0ZWVrcHJvZXZlbiBiZXNsdWl0ZW4gd2UgZGF0IHZyb3V3ZW4gZW4gbWFubmVuIGdlbWlkZGVsZCBuaWV0IHNpZ25pZmljYW50IHZlcnNjaGlsbGVuIGluIGxlbmd0ZS4gRW4gaW4gYHIgc3VtKHJlcyRwdmFsdWU8MC4wNSZyZXMkdmVyc2NoaWw+MClgIGJlc2x1aXRlbiB3ZSBkYXQgdnJvdXdlbiBnZW1pZGRlbGQgc2lnbmlmaWNhbnQgZ3JvdGVyIHppam4gZGFuIG1hbm5lbi4KCi0gRGUgc3RlZWtwcm9lZiBkaWUgd2UgdG9vbmRlbiB3YWFydWl0IHdlIHpvdWRlbiBiZXNsdWl0ZW4gZGF0IHZyb3V3ZW4gc2lnbmlmaWNhbnQgZ3JvdGVyIHppam4gZGFuIG1hbm5lbiBpcyBoZWVsIG9ud2FhcnNjaGlqbmxpamsuIEVyIG1vZXN0ZW4gYHIgcGFzdGUoc2VlZClgIHN0ZWVrcHJvZXZlbiB3b3JkZW4gZ2V0cm9ra2VuIG9tIGRlemUgZXh0cmVtZSBzdGVla3Byb2VmIHRlIHZpbmRlbi4KCkhldCBmZWl0IGRhdCB3ZSBpbiB2ZWVsIHN0ZWVrcHJvZXZlbiByZXN1bHRhdGVuIHZpbmRlbiBkaWUgc3RhdGlzdGlzY2ggbmlldCBzaWduaWZpY2FudCB6aWpuIGtvbXQgb21kYXQgZGUgc3RhdGlzdGlzY2hlIHRvZXRzIGVlbiB0ZSBsYWdlIGtyYWNodCBoZWVmdCBvbSBoZXQgdmVyc2NoaWwgdGUgZGV0ZWN0ZXJlbiB3YW5uZWVyIGVyIG1hYXIgNSBvYnNlcnZhdGllcyB6aWpuIHBlciBncm9lcC4KCi0tLQoKIyMgR3JvdGVyZSBzdGVla3Byb2VmPwoKV2F0IGdlYmV1cnQgZXIgYWxzIHdlIGRlIHN0ZWVrcHJvZWYgdmVyaG9nZW4gbmFhciA1MCBvYnNlcnZhdGllcyBwZXIgZ3JvZXA/CgoKYGBge3J9CiMgQWFudGFsIHNpbXVsYXRpZXMgZW4gc3RlZWtwcm9lZmdyb290dGUgcGVyIGdyb2VwCm5TaW0gPC0gMTAwMDAKblNhbXAgPC0gNTAKCiMgV2UgZmlsdGVyZW4gZGUgZGF0YSB2b29yYWYgem9kYXQgd2UgZGl0IG5pZXQgdGVsa2VucyBvcG5pZXV3IGhvZXZlbiB0ZSBkb2VuCmZlbSA8LSBuaGFuZXNTdWIgJT4lCiAgZmlsdGVyKEdlbmRlciA9PSAiZmVtYWxlIikKCm1hbCA8LSBuaGFuZXNTdWIgJT4lCiAgZmlsdGVyKEdlbmRlciA9PSAibWFsZSIpCgojIFNpbXVsYXRpZSBzdHVkaWUKIyBPbSBzbmVsbGUgZnVuY3RpZXMgdGUga3VubmVuIGdlYnJ1aWtlbiBuZW1lbiB3ZSBlZXJzdCBuU2ltIHN0ZWVrcHJvZXZlbiBlbiBiZXJla2VuZW4gd2UgZGFhcm5hIGFsbGVzLgoKZmVtU2FtcHMgPC0gbWFsU2FtcHMgPC0gbWF0cml4KE5BLCBucm93ID0gblNhbXAsIG5jb2wgPSBuU2ltKQpmb3IgKGkgaW4gMTpuU2ltKQp7CiAgZmVtU2FtcHNbLGldIDwtIHNhbXBsZShmZW0kSGVpZ2h0LCBuU2FtcCkKICBtYWxTYW1wc1ssaV0gPC0gc2FtcGxlKG1hbCRIZWlnaHQsIG5TYW1wKQp9CgpyZXMgPC0gZGF0YS5mcmFtZSgKICB2ZXJzY2hpbCA9IGNvbE1lYW5zKGZlbVNhbXBzKSAtIGNvbE1lYW5zKG1hbFNhbXBzKSwKICBSZmFzdDo6dHRlc3RzKGZlbVNhbXBzLCBtYWxTYW1wcykKICApCgpzdW0ocmVzJHB2YWx1ZSA8IDAuMDUgJiByZXMkdmVyc2NoaWwgPCAwKQpzdW0ocmVzJHB2YWx1ZSA+PSAwLjA1KQpzdW0ocmVzJHB2YWx1ZSA8IDAuMDUgJiByZXMkdmVyc2NoaWwgPiAwKQoKcmVzICU+JQogIGdncGxvdChhZXMoeD12ZXJzY2hpbCx5PS1sb2cxMChwdmFsdWUpLGNvbG9yPXB2YWx1ZTwwLjA1KSkgKwogIGdlb21fcG9pbnQoKSArCiAgeGxhYigiR2VtaWRkZWxkIFZlcnNjaGlsIChjbSkiKSArCiAgeWxhYigiU3RhdGlzdGlzY2hlIFNpZ25pZmljYW50aWUgKC1sb2cxMCBwKSIpCgpyZXMgJT4lCiAgZ2dwbG90KGFlcyh5PXZlcnNjaGlsKSkgKwogIGdlb21fYm94cGxvdCgpICsKICB5bGFiKCJHZW1pZGRlbGQgVmVyc2NoaWwgKGNtKSIpCiAgeGxhYigiIikKYGBgCgotLS0KCiNDYXNlIHN0dWR5OiBTYWxrIHZhY2NpbgoKLSBJbiAxOTE2LCBicmFrIGRlIGVlcnN0ZSBncm90ZSBwb2xpbyBlcGlkZW1pZSB1aXQgaW4gZGUgVVNBLgotIEJlZ2luIGRlIGphcmVuIDUwIG9udHdpa2tlbGRlIEpvaG4gU2FsayBlZW4gdmFjY2luIG1ldCBiZWxvdmVuZGUgcmVzdWx0YXRlbiBpbiBoZXQgbGFiLgotIEluIDE5NTQsIGhlZWZ0IGRlIE5hdGlvbmFsIEZvdW5kYXRpb24KZm9yIEluZmFudGlsZSBQYXJhbHlzaXMgKE5GSVApIGVlbiBncm90ZSBzdHVkaWUgb3BnZXpldCBvbSBkZSBlZmZlY3Rpdml0ZWl0IHZhbiBoZXQgU2FsayB2YWNjaW4gbmEgdGUgZ2Fhbi4KLSBWZXJvbmRlcnN0ZWwgZGF0IGRlIE5GSVAgaW4gMTk1NCBlZW4gZ3Jvb3QgYWFudGFsIGtpbmRlcmVuIHpvdSBoZWJiZW4gZ2V2YWNjaW5lZXJkLCB3YXQgem91ZGVuIHplIGRhbiBrdW5uZW4gYmVzbHVpdGVuIGFscyBkZSBwb2xpbyBpbmNpZGVudGllIGluIDE5NTQgbGFnZXIgd2FzIGRhbiBpbiAxOTUzPwoKLS0tCgojIyBORklQIFN0dWR5CiMjIyBEZXNpZ24KCi0gR3JvdGUgc2ltdWx0YW5lIHN0dWRpZSBtZXQgZ2V2YWNjaW5lZXJkZSBraW5kZXJlbiAoY2FzZXMpIGVuIG9uZ2V2YWNjaW5lZXJkZSBraW5kZXJlbiAoY29udHJvbGVzKS4KLSBJbiBzY2hvbGVuIHZhbiBkaXN0cmljdGVuIG1ldCBob2dlIHBvbGlvIGluY2lkZW50aWUuCi0gQ2FzZXM6IGtpbmRlcmVuIHZhbiBkZSB0d2VlZGUgZ3JhYWQgdmFuIGhldCBsYWdlciBvbmRlcndpanMgd2FhcnZhbiBkZSBvdWRlcnMgdG9lc3RlbWRlbiBtZXQgdmFjY2luYXRpZS4KLSBDb250cm9sZXM6IGtpbmRlcmVuIHZhbiBkZSBlZXJzdGUgZW4gZGVyZGUgZ3JhYWQuCgojIyMgRGF0YQpgYGB7cn0KbmZpcCA8LSB0aWJibGUoCiAgZ3JvdXA9YygiY2FzZXMiLCJjb250cm9scyIsIm5vQ29uY2VudCIpLAogIGdyYWRlPWMoImcyIiwiZzFnMyIsImcyIiksCiAgdmFjY2luPWMoInllcyIsIm5vIiwibm8iKSwKICB0b3RhbD1jKDIyMTk5OCw3MjUxNzMsMTIzNjA1KSwKICBwb2xpbz1jKDU0LDM5MSw1NikKICApICU+JQogIG11dGF0ZShub1BvbGlvID0gdG90YWwgLSBwb2xpbykKa25pdHI6OmthYmxlKG5maXApCmBgYAoKVmVyZ2VsaWprIGRlIHBvbGlvIGluY2lkZW50aWU/CgotLS0KCmBgYHtyfQpuZmlwIDwtIG5maXAgJT4lCiAgbXV0YXRlKGluY2lkZW5jZVBNID0gcm91bmQobmZpcCRwb2xpby9uZmlwJHRvdGFsKjFlNiwwKSkKa25pdHI6OmthYmxlKG5maXApCmBgYAoKV2F0IGt1bm5lbiB3ZSBjb25jbHVkZXJlbj8KCi0tLQoKIyMgQ29uZm91bmRpbmcKCgpgYGB7cixlY2hvPUZBTFNFLCBmaWcuYWxpZ24gPSAiY2VudGVyIixvdXQud2lkdGggPSAnNTAlJ30KcGxvdChjKDAsMCwxKSxjKC0yLDIsMCkscGNoPWMoIlMiLCJWIiwiUCIpLHhheHQ9Im5vbmUiLHlheHQ9Im5vbmUiLGF4ZXM9RkFMU0UseGxhYj0iIix5bGFiPSIiLGNleD00LHlsaW09YygtMi4yLDIuMikpCmFycm93cyh4MD0wLjEseDE9LjkseTA9MS44LHkxPTAuMSxsd2Q9NCkKYXJyb3dzKHgwPTAuMSx4MT0uOSx5MD0tMS44LHkxPS0wLjIsbHdkPTQpCmFycm93cyh4MD0wLHgxPTAseTA9LTEuNCx5MT0xLjQsbHdkPTQpCmBgYAoKCi0gV2Ugb2JzZXJ2ZXJlbiBlZW4gbGFnZXJlIHBvbGlvIChQKSBpbmNpZGVudGllIHZvb3Iga2luZGVyZW4gYmlqIHdpZSBkZSBvdWRlcnMgZ2VlbiB0b2VzdGVtbWluZyBnYXZlbiBkYW4gaW4gZGUgY29udHJvbGUgZ3JvZXAuICAKCi0gVG9lc3RlbW1pbmcgdm9vciB2YWNjaW5hdGllIChWKSBpcyBnZWFzc29jaWVlcmQgbWV0IGRlIHNvY2lvLWVjb25vbWlzY2hlIHN0YXR1cyAoUykuCgotIEtpbmRlcmVuIHZhbiBsYWdlcmUgc29jaW8tZWNvbm9taXNjaGUgc3RhdHVzIHppam4gbWVlciByZXNpc3RlbnQgdGVnZW4gZGUgemlla3RlLgoKLSBEZSBncm9lcGVuIHZhbiBjYXNlcyBlbiBjb250cm9sZXMgemlqbiBuaWV0IHZlcmdlbGlqa2JhYXIKICAgIC0gdmVyc2NoaWwgaW4gbGVlZnRpamQKICAgIC0gdmVyc2NoaWwgaW4gc29jaW8tZWNvbm9taXNjaGUgc3RhdHVzIGVuCiAgICAtIHZlcnNjaGlsIGluIHZhdGJhYXJoZWlkIHZvb3IgZGUgemlla3RlLgoKLS0tCgojIyBTYWxrIFN0dWR5CgojIyMgRGVzaWduCkVlbiBuaWV1d2Ugc3R1ZGllIHdlcmQgdWl0Z2V2b2VyZDogZHViYmVsIGJsaW5kZSBnZXJhbmRvbWlzZWVyZGUgc3R1ZGllLgoKICAtIEtpbmRlcmVuIHdvcmRlbiBhdCByYW5kb20gdG9lZ2V3ZXplbiBhYW4gY29udHJvbGUgb2YgY2FzZSBhcm0gdmFuIGhldCBleHBlcmltZW50IG5hZGF0IGRlIG91ZGVycyB0b2VzdGVtZGVuIG1ldCB2YWNjaW5hdGllLgogIC0gQ29udHJvbGU6IHZhY2NpbmF0aWUgbWV0IHBsYWNlYm8KICAtIFRyZWF0bWVudDogdmFjY2luYXRpZSBtZXQgdmFjY2luCiAgLSBEb3VibGUgYmxpbmRpbmc6CiAgICAtIG91ZGVycyBlbiBraW5kZXJlbiB3ZXRlbiBuaWV0IG9mIHplIHdlcmRlbiBnZXZhY2NpbmVlcmQgb2YgbmlldAogICAgLSBtZWRpc2NoZSBzdGFmIGVuIG9uZGVyem9la2VycyB3ZXRlbiBuaWV0IG9mIGhldCBraW5kIGhldCB2YWNjaW4gb2YgZGUgcGxhY2VibyBrcmVlZwoKLS0tCgojIyMgRGF0YQoKYGBge3J9CnNhbGsgPC0gZGF0YS5mcmFtZSgKICBncm91cD1jKCJjYXNlcyIsImNvbnRyb2wiLCJub0NvbmNlbnQiKSwKICB0cmVhdG1lbnQ9YygidmFjY2luZSIsInBsYWNlYm8iLCJub25lIiksCiAgdG90YWw9YygyMDA3NDUsMjAxMjI5LCAzMzg3NzgpLHBvbGlvPWMoNTcsMTQyLDE1NykKICApICU+JQogIG11dGF0ZSgKICAgIG5vUG9saW8gPSB0b3RhbC1wb2xpbywKICAgIGluY2lkZW5jZVBNID0gcm91bmQocG9saW8vdG90YWwqMWU2LDApCiAgICApCmtuaXRyOjprYWJsZShzYWxrKQpgYGAKCi0gV2Ugb2JzZXJ2ZXJlbiBlZW4gdmVlbCBncm90ZXIgZWZmZWN0IG51IGRhdCBjYXNlcyBlbiBjb250cm9sZXMgdmVyZ2VsaWprYmFhciB6aWpuLCBpbmNpZGVudGllIHZhbiByZXNwZWN0aWV2ZWxpamsgYHIgc2FsayRpbmNpZGVuY2VQTVsxXWAgIGFuZCBgciBzYWxrJGluY2lkZW5jZVBNWzJdYCBwZXIgbWlsam9lbi4KCi0gRGUgcG9saW8gaW5jaWRlbnRpZSB2b29yIGtpbmRlcmVuIGRpZSBnZWVuIHRvZXN0ZW1taW5nIGdldmVuIGJsaWpmdCB2ZXJnZWxpamtiYWFyICBgciBuZmlwJGluY2lkZW5jZVBNWzNdYCBhbmQgYHIgc2FsayRpbmNpZGVuY2VQTVszXWAgcGVyIG1pbGpvZW4gcmVzcGVjdGlldmVsaWprIGluIHRoZSBORklQIGFuZCBTYWxrIHN0dWR5LgoKLS0tCgojIFJvbCB2YW4gU3RhdGlzdGllawoKLSBXZSBoZWJiZW4gZ2V6aWVuIGRhdAogICAgLSBoZXQgYmVsYW5ncmlqayBpcyBvbSBkZSBzY29wZSB2YW4gZGUgc3R1ZGllIGdvZWQgdGUgc3BlY2lmacOrcmVuIHZvb3IgZGUgc3RhcnQgdmFuIGhldCBleHBlcmltZW50CiAgICAtIHJhbmRvbWlzYXRpZSBub2RpZyBpcyBvbSBlZW4gcmVwcmVzZW50YXRpZXZlIHN0ZWVrcHJvZWYgdGUgbmVtZW4KICAgIC0gc3RlZWtwcm9lZiBncm9vdHRlIGlzIGhlZWwgYmVsYW5ncmlqawogICAgLSB3ZSBtb2V0ZW4gb25zIGJld3VzdCB6aWpuIHZhbiBDb25mb3VuZGluZwogICAgLSBlZW4gZ29lZGUgY29udHJvbGUgaXMgYmVsYW5ncmlqawoKCiRccmlnaHRhcnJvdyQgR29lZGUgcHJvZWZvcHpldCBpcyBjcnVjaWFhbCEKCi0tLQoKLSBXZSBoZWJiZW4gb29rIGdlb2JzZXJ2ZWVyZCBkYXQgZXIgdmFyaWFiaWxpdGVpdCBpcyBpbiBkZSBwb3B1bGF0aWUKLSBXZSBrdW5uZW4gbWFhciBlZW4gYmVwZXJrdGUgc3RlZWtwcm9lZiBuZW1lbiB1aXQgZGUgcG9wdWxhdGllCgokXHJpZ2h0YXJyb3ckIG9uemVrZXJoZWlkIGluIGRlIHJlc3VsdGF0ZW4KJFxyaWdodGFycm93JCBvbnpla2VyaGVpZCBpbiBkZSBjb25jbHVzaWVzCgoKLS0tCgotIFN0YXRpc3RpZWsgaXMgZGUgd2V0ZW5zY2hhcCB2b29yIGhldAogICAgMS4gdmVyemFtZWxlbiAoZXhwZXJpbWVudGVlbCBkZXNpZ24pLAogICAgMi4gZXhwbG9yZW4gKGRhdGEgZXhwbG9yYXRpb24pIGVuCiAgICAzLiBsZXJlbiB2YW4gZGF0YSB6b2RhdCB3ZSBoZXRnZWVuIHdlIG9ic2VydmVyZW4gaW4gZGUgc3RlZWtwcm9lZiB6b3VkZW4ga3VubmVuIHZlcmFsZ2VtZW5lbiBuYWFyIGRlIHBvcHVsYXRpZSB0ZXJ3aWpsIHdlIGRlIG9uemVrZXJoZWlkIHF1YW50aWZpY2VyZW4sIGNvbnRyb2xlcmVuIGVuIHJhcHBvcnRlcmVuIChzdGF0aXN0aXNjaCBtb2RlbGxlcmVuIGVuIHN0YXRpc3Rpc2NoZSBiZXNsdWl0dm9ybWluZykuCgotIFN0YXRpc3RpZWsgc3BlZWx0IGRhYXJvbSBlZW4gaGVlbCBiZWxhbmdyaWprZSByb2wgaW4gem93YXQgYWxsZSB3ZXRlbnNjaGFwcGVuCgoKIyBbSG9tZV0oaHR0cHM6Ly9ndHBiLmdpdGh1Yi5pby9zYmMyMC8pIHstfQo=